commonmarker 0.23.10 → 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1192 -0
  3. data/Cargo.toml +6 -0
  4. data/README.md +145 -203
  5. data/ext/commonmarker/Cargo.toml +13 -0
  6. data/ext/commonmarker/extconf.rb +3 -6
  7. data/ext/commonmarker/src/lib.rs +153 -0
  8. data/ext/commonmarker/src/options.rs +144 -0
  9. data/ext/commonmarker/src/plugins/syntax_highlighting.rs +74 -0
  10. data/ext/commonmarker/src/plugins.rs +3 -0
  11. data/ext/commonmarker/src/utils.rs +8 -0
  12. data/lib/commonmarker/config.rb +85 -40
  13. data/lib/commonmarker/constants.rb +7 -0
  14. data/lib/commonmarker/extension.rb +14 -0
  15. data/lib/commonmarker/renderer.rb +1 -127
  16. data/lib/commonmarker/utils.rb +22 -0
  17. data/lib/commonmarker/version.rb +2 -2
  18. data/lib/commonmarker.rb +14 -29
  19. metadata +35 -187
  20. data/Rakefile +0 -109
  21. data/bin/commonmarker +0 -118
  22. data/commonmarker.gemspec +0 -38
  23. data/ext/commonmarker/arena.c +0 -104
  24. data/ext/commonmarker/autolink.c +0 -508
  25. data/ext/commonmarker/autolink.h +0 -8
  26. data/ext/commonmarker/blocks.c +0 -1622
  27. data/ext/commonmarker/buffer.c +0 -278
  28. data/ext/commonmarker/buffer.h +0 -116
  29. data/ext/commonmarker/case_fold_switch.inc +0 -4327
  30. data/ext/commonmarker/chunk.h +0 -135
  31. data/ext/commonmarker/cmark-gfm-core-extensions.h +0 -54
  32. data/ext/commonmarker/cmark-gfm-extension_api.h +0 -737
  33. data/ext/commonmarker/cmark-gfm-extensions_export.h +0 -42
  34. data/ext/commonmarker/cmark-gfm.h +0 -833
  35. data/ext/commonmarker/cmark-gfm_export.h +0 -42
  36. data/ext/commonmarker/cmark-gfm_version.h +0 -7
  37. data/ext/commonmarker/cmark.c +0 -55
  38. data/ext/commonmarker/cmark_ctype.c +0 -44
  39. data/ext/commonmarker/cmark_ctype.h +0 -33
  40. data/ext/commonmarker/commonmark.c +0 -514
  41. data/ext/commonmarker/commonmarker.c +0 -1308
  42. data/ext/commonmarker/commonmarker.h +0 -16
  43. data/ext/commonmarker/config.h +0 -76
  44. data/ext/commonmarker/core-extensions.c +0 -27
  45. data/ext/commonmarker/entities.inc +0 -2138
  46. data/ext/commonmarker/ext_scanners.c +0 -879
  47. data/ext/commonmarker/ext_scanners.h +0 -24
  48. data/ext/commonmarker/footnotes.c +0 -63
  49. data/ext/commonmarker/footnotes.h +0 -27
  50. data/ext/commonmarker/houdini.h +0 -57
  51. data/ext/commonmarker/houdini_href_e.c +0 -100
  52. data/ext/commonmarker/houdini_html_e.c +0 -66
  53. data/ext/commonmarker/houdini_html_u.c +0 -149
  54. data/ext/commonmarker/html.c +0 -502
  55. data/ext/commonmarker/html.h +0 -27
  56. data/ext/commonmarker/inlines.c +0 -1788
  57. data/ext/commonmarker/inlines.h +0 -29
  58. data/ext/commonmarker/iterator.c +0 -159
  59. data/ext/commonmarker/iterator.h +0 -26
  60. data/ext/commonmarker/latex.c +0 -468
  61. data/ext/commonmarker/linked_list.c +0 -37
  62. data/ext/commonmarker/man.c +0 -274
  63. data/ext/commonmarker/map.c +0 -129
  64. data/ext/commonmarker/map.h +0 -44
  65. data/ext/commonmarker/node.c +0 -1045
  66. data/ext/commonmarker/node.h +0 -167
  67. data/ext/commonmarker/parser.h +0 -59
  68. data/ext/commonmarker/plaintext.c +0 -218
  69. data/ext/commonmarker/plugin.c +0 -36
  70. data/ext/commonmarker/plugin.h +0 -34
  71. data/ext/commonmarker/references.c +0 -43
  72. data/ext/commonmarker/references.h +0 -26
  73. data/ext/commonmarker/registry.c +0 -63
  74. data/ext/commonmarker/registry.h +0 -24
  75. data/ext/commonmarker/render.c +0 -213
  76. data/ext/commonmarker/render.h +0 -62
  77. data/ext/commonmarker/scanners.c +0 -14056
  78. data/ext/commonmarker/scanners.h +0 -70
  79. data/ext/commonmarker/scanners.re +0 -341
  80. data/ext/commonmarker/strikethrough.c +0 -167
  81. data/ext/commonmarker/strikethrough.h +0 -9
  82. data/ext/commonmarker/syntax_extension.c +0 -149
  83. data/ext/commonmarker/syntax_extension.h +0 -34
  84. data/ext/commonmarker/table.c +0 -917
  85. data/ext/commonmarker/table.h +0 -12
  86. data/ext/commonmarker/tagfilter.c +0 -60
  87. data/ext/commonmarker/tagfilter.h +0 -8
  88. data/ext/commonmarker/tasklist.c +0 -156
  89. data/ext/commonmarker/tasklist.h +0 -8
  90. data/ext/commonmarker/utf8.c +0 -317
  91. data/ext/commonmarker/utf8.h +0 -35
  92. data/ext/commonmarker/xml.c +0 -182
  93. data/lib/commonmarker/node/inspect.rb +0 -47
  94. data/lib/commonmarker/node.rb +0 -83
  95. data/lib/commonmarker/renderer/html_renderer.rb +0 -256
@@ -1,182 +0,0 @@
1
- #include <stdlib.h>
2
- #include <stdio.h>
3
- #include <string.h>
4
- #include <assert.h>
5
-
6
- #include "config.h"
7
- #include "cmark-gfm.h"
8
- #include "node.h"
9
- #include "buffer.h"
10
- #include "houdini.h"
11
- #include "syntax_extension.h"
12
-
13
- #define BUFFER_SIZE 100
14
- #define MAX_INDENT 40
15
-
16
- // Functions to convert cmark_nodes to XML strings.
17
-
18
- static void escape_xml(cmark_strbuf *dest, const unsigned char *source,
19
- bufsize_t length) {
20
- houdini_escape_html0(dest, source, length, 0);
21
- }
22
-
23
- struct render_state {
24
- cmark_strbuf *xml;
25
- int indent;
26
- };
27
-
28
- static CMARK_INLINE void indent(struct render_state *state) {
29
- int i;
30
- for (i = 0; i < state->indent && i < MAX_INDENT; i++) {
31
- cmark_strbuf_putc(state->xml, ' ');
32
- }
33
- }
34
-
35
- static int S_render_node(cmark_node *node, cmark_event_type ev_type,
36
- struct render_state *state, int options) {
37
- cmark_strbuf *xml = state->xml;
38
- bool literal = false;
39
- cmark_delim_type delim;
40
- bool entering = (ev_type == CMARK_EVENT_ENTER);
41
- char buffer[BUFFER_SIZE];
42
-
43
- if (entering) {
44
- indent(state);
45
- cmark_strbuf_putc(xml, '<');
46
- cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
47
-
48
- if (options & CMARK_OPT_SOURCEPOS && node->start_line != 0) {
49
- snprintf(buffer, BUFFER_SIZE, " sourcepos=\"%d:%d-%d:%d\"",
50
- node->start_line, node->start_column, node->end_line,
51
- node->end_column);
52
- cmark_strbuf_puts(xml, buffer);
53
- }
54
-
55
- if (node->extension && node->extension->xml_attr_func) {
56
- const char* r = node->extension->xml_attr_func(node->extension, node);
57
- if (r != NULL)
58
- cmark_strbuf_puts(xml, r);
59
- }
60
-
61
- literal = false;
62
-
63
- switch (node->type) {
64
- case CMARK_NODE_DOCUMENT:
65
- cmark_strbuf_puts(xml, " xmlns=\"http://commonmark.org/xml/1.0\"");
66
- break;
67
- case CMARK_NODE_TEXT:
68
- case CMARK_NODE_CODE:
69
- case CMARK_NODE_HTML_BLOCK:
70
- case CMARK_NODE_HTML_INLINE:
71
- cmark_strbuf_puts(xml, " xml:space=\"preserve\">");
72
- escape_xml(xml, node->as.literal.data, node->as.literal.len);
73
- cmark_strbuf_puts(xml, "</");
74
- cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
75
- literal = true;
76
- break;
77
- case CMARK_NODE_LIST:
78
- switch (cmark_node_get_list_type(node)) {
79
- case CMARK_ORDERED_LIST:
80
- cmark_strbuf_puts(xml, " type=\"ordered\"");
81
- snprintf(buffer, BUFFER_SIZE, " start=\"%d\"",
82
- cmark_node_get_list_start(node));
83
- cmark_strbuf_puts(xml, buffer);
84
- delim = cmark_node_get_list_delim(node);
85
- if (delim == CMARK_PAREN_DELIM) {
86
- cmark_strbuf_puts(xml, " delim=\"paren\"");
87
- } else if (delim == CMARK_PERIOD_DELIM) {
88
- cmark_strbuf_puts(xml, " delim=\"period\"");
89
- }
90
- break;
91
- case CMARK_BULLET_LIST:
92
- cmark_strbuf_puts(xml, " type=\"bullet\"");
93
- break;
94
- default:
95
- break;
96
- }
97
- snprintf(buffer, BUFFER_SIZE, " tight=\"%s\"",
98
- (cmark_node_get_list_tight(node) ? "true" : "false"));
99
- cmark_strbuf_puts(xml, buffer);
100
- break;
101
- case CMARK_NODE_HEADING:
102
- snprintf(buffer, BUFFER_SIZE, " level=\"%d\"", node->as.heading.level);
103
- cmark_strbuf_puts(xml, buffer);
104
- break;
105
- case CMARK_NODE_CODE_BLOCK:
106
- if (node->as.code.info.len > 0) {
107
- cmark_strbuf_puts(xml, " info=\"");
108
- escape_xml(xml, node->as.code.info.data, node->as.code.info.len);
109
- cmark_strbuf_putc(xml, '"');
110
- }
111
- cmark_strbuf_puts(xml, " xml:space=\"preserve\">");
112
- escape_xml(xml, node->as.code.literal.data, node->as.code.literal.len);
113
- cmark_strbuf_puts(xml, "</");
114
- cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
115
- literal = true;
116
- break;
117
- case CMARK_NODE_CUSTOM_BLOCK:
118
- case CMARK_NODE_CUSTOM_INLINE:
119
- cmark_strbuf_puts(xml, " on_enter=\"");
120
- escape_xml(xml, node->as.custom.on_enter.data,
121
- node->as.custom.on_enter.len);
122
- cmark_strbuf_putc(xml, '"');
123
- cmark_strbuf_puts(xml, " on_exit=\"");
124
- escape_xml(xml, node->as.custom.on_exit.data,
125
- node->as.custom.on_exit.len);
126
- cmark_strbuf_putc(xml, '"');
127
- break;
128
- case CMARK_NODE_LINK:
129
- case CMARK_NODE_IMAGE:
130
- cmark_strbuf_puts(xml, " destination=\"");
131
- escape_xml(xml, node->as.link.url.data, node->as.link.url.len);
132
- cmark_strbuf_putc(xml, '"');
133
- cmark_strbuf_puts(xml, " title=\"");
134
- escape_xml(xml, node->as.link.title.data, node->as.link.title.len);
135
- cmark_strbuf_putc(xml, '"');
136
- break;
137
- default:
138
- break;
139
- }
140
- if (node->first_child) {
141
- state->indent += 2;
142
- } else if (!literal) {
143
- cmark_strbuf_puts(xml, " /");
144
- }
145
- cmark_strbuf_puts(xml, ">\n");
146
-
147
- } else if (node->first_child) {
148
- state->indent -= 2;
149
- indent(state);
150
- cmark_strbuf_puts(xml, "</");
151
- cmark_strbuf_puts(xml, cmark_node_get_type_string(node));
152
- cmark_strbuf_puts(xml, ">\n");
153
- }
154
-
155
- return 1;
156
- }
157
-
158
- char *cmark_render_xml(cmark_node *root, int options) {
159
- return cmark_render_xml_with_mem(root, options, cmark_node_mem(root));
160
- }
161
-
162
- char *cmark_render_xml_with_mem(cmark_node *root, int options, cmark_mem *mem) {
163
- char *result;
164
- cmark_strbuf xml = CMARK_BUF_INIT(mem);
165
- cmark_event_type ev_type;
166
- cmark_node *cur;
167
- struct render_state state = {&xml, 0};
168
-
169
- cmark_iter *iter = cmark_iter_new(root);
170
-
171
- cmark_strbuf_puts(state.xml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
172
- cmark_strbuf_puts(state.xml,
173
- "<!DOCTYPE document SYSTEM \"CommonMark.dtd\">\n");
174
- while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
175
- cur = cmark_iter_get_node(iter);
176
- S_render_node(cur, ev_type, &state, options);
177
- }
178
- result = (char *)cmark_strbuf_detach(&xml);
179
-
180
- cmark_iter_free(iter);
181
- return result;
182
- }
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "pp"
4
-
5
- module CommonMarker
6
- class Node
7
- module Inspect
8
- PP_INDENT_SIZE = 2
9
-
10
- def inspect
11
- PP.pp(self, +"", Float::INFINITY)
12
- end
13
-
14
- # @param printer [PrettyPrint] pp
15
- def pretty_print(printer)
16
- printer.group(PP_INDENT_SIZE, "#<#{self.class}(#{type}):", ">") do
17
- printer.breakable
18
-
19
- attrs = [:sourcepos, :string_content, :url, :title, :header_level, :list_type, :list_start, :list_tight, :fence_info].map do |name|
20
- [name, __send__(name)]
21
- rescue NodeError
22
- nil
23
- end.compact
24
-
25
- printer.seplist(attrs) do |name, value|
26
- printer.text("#{name}=")
27
- printer.pp(value)
28
- end
29
-
30
- if first_child
31
- printer.breakable
32
- printer.group(PP_INDENT_SIZE) do
33
- children = []
34
- node = first_child
35
- while node
36
- children << node
37
- node = node.next
38
- end
39
- printer.text("children=")
40
- printer.pp(children)
41
- end
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end
@@ -1,83 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "commonmarker/node/inspect"
4
-
5
- module CommonMarker
6
- class Node
7
- include Enumerable
8
- include Inspect
9
-
10
- # Public: An iterator that "walks the tree," descending into children recursively.
11
- #
12
- # blk - A {Proc} representing the action to take for each child
13
- def walk(&block)
14
- return enum_for(:walk) unless block
15
-
16
- yield self
17
- each do |child|
18
- child.walk(&block)
19
- end
20
- end
21
-
22
- # Public: Convert the node to an HTML string.
23
- #
24
- # options - A {Symbol} or {Array of Symbol}s indicating the render options
25
- # extensions - An {Array of Symbol}s indicating the extensions to use
26
- #
27
- # Returns a {String}.
28
- def to_html(options = :DEFAULT, extensions = [])
29
- opts = Config.process_options(options, :render)
30
- _render_html(opts, extensions).force_encoding("utf-8")
31
- end
32
-
33
- # Public: Convert the node to an XML string.
34
- #
35
- # options - A {Symbol} or {Array of Symbol}s indicating the render options
36
- #
37
- # Returns a {String}.
38
- def to_xml(options = :DEFAULT)
39
- opts = Config.process_options(options, :render)
40
- _render_xml(opts).force_encoding("utf-8")
41
- end
42
-
43
- # Public: Convert the node to a CommonMark string.
44
- #
45
- # options - A {Symbol} or {Array of Symbol}s indicating the render options
46
- # width - Column to wrap the output at
47
- #
48
- # Returns a {String}.
49
- def to_commonmark(options = :DEFAULT, width = 120)
50
- opts = Config.process_options(options, :render)
51
- _render_commonmark(opts, width).force_encoding("utf-8")
52
- end
53
-
54
- # Public: Convert the node to a plain text string.
55
- #
56
- # options - A {Symbol} or {Array of Symbol}s indicating the render options
57
- # width - Column to wrap the output at
58
- #
59
- # Returns a {String}.
60
- def to_plaintext(options = :DEFAULT, width = 120)
61
- opts = Config.process_options(options, :render)
62
- _render_plaintext(opts, width).force_encoding("utf-8")
63
- end
64
-
65
- # Public: Iterate over the children (if any) of the current pointer.
66
- def each
67
- return enum_for(:each) unless block_given?
68
-
69
- child = first_child
70
- while child
71
- nextchild = child.next
72
- yield child
73
- child = nextchild
74
- end
75
- end
76
-
77
- # Deprecated: Please use `each` instead
78
- def each_child(&block)
79
- warn("[DEPRECATION] `each_child` is deprecated. Please use `each` instead.")
80
- each(&block)
81
- end
82
- end
83
- end
@@ -1,256 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module CommonMarker
4
- class HtmlRenderer < Renderer
5
- def document(_)
6
- super
7
- out("</ol>\n</section>\n") if @written_footnote_ix
8
- end
9
-
10
- def header(node)
11
- block do
12
- out("<h", node.header_level, "#{sourcepos(node)}>", :children,
13
- "</h", node.header_level, ">")
14
- end
15
- end
16
-
17
- def paragraph(node)
18
- if @in_tight && node.parent.type != :blockquote
19
- out(:children)
20
- else
21
- block do
22
- container("<p#{sourcepos(node)}>", "</p>") do
23
- out(:children)
24
- if node.parent.type == :footnote_definition && node.next.nil?
25
- out(" ")
26
- out_footnote_backref
27
- end
28
- end
29
- end
30
- end
31
- end
32
-
33
- def list(node)
34
- old_in_tight = @in_tight
35
- @in_tight = node.list_tight
36
-
37
- block do
38
- if node.list_type == :bullet_list
39
- container("<ul#{sourcepos(node)}>\n", "</ul>") do
40
- out(:children)
41
- end
42
- else
43
- start = if node.list_start == 1
44
- "<ol#{sourcepos(node)}>\n"
45
- else
46
- "<ol start=\"#{node.list_start}\"#{sourcepos(node)}>\n"
47
- end
48
- container(start, "</ol>") do
49
- out(:children)
50
- end
51
- end
52
- end
53
-
54
- @in_tight = old_in_tight
55
- end
56
-
57
- def list_item(node)
58
- block do
59
- tasklist_data = tasklist(node)
60
- container("<li#{sourcepos(node)}#{tasklist_data}>#{" " if tasklist?(node)}", "</li>") do
61
- out(:children)
62
- end
63
- end
64
- end
65
-
66
- def tasklist(node)
67
- return "" unless tasklist?(node)
68
-
69
- state = if checked?(node)
70
- 'checked="" disabled=""'
71
- else
72
- 'disabled=""'
73
- end
74
- "><input type=\"checkbox\" #{state} /"
75
- end
76
-
77
- def blockquote(node)
78
- block do
79
- container("<blockquote#{sourcepos(node)}>\n", "</blockquote>") do
80
- out(:children)
81
- end
82
- end
83
- end
84
-
85
- def hrule(node)
86
- block do
87
- out("<hr#{sourcepos(node)} />")
88
- end
89
- end
90
-
91
- def code_block(node)
92
- block do
93
- if option_enabled?(:GITHUB_PRE_LANG)
94
- out("<pre#{sourcepos(node)}")
95
- out(' lang="', node.fence_info.split(/\s+/)[0], '"') if node.fence_info && !node.fence_info.empty?
96
- out("><code>")
97
- else
98
- out("<pre#{sourcepos(node)}><code")
99
- if node.fence_info && !node.fence_info.empty?
100
- out(' class="language-', node.fence_info.split(/\s+/)[0], '">')
101
- else
102
- out(">")
103
- end
104
- end
105
- out(escape_html(node.string_content))
106
- out("</code></pre>")
107
- end
108
- end
109
-
110
- def html(node)
111
- block do
112
- if option_enabled?(:UNSAFE)
113
- out(tagfilter(node.string_content))
114
- else
115
- out("<!-- raw HTML omitted -->")
116
- end
117
- end
118
- end
119
-
120
- def inline_html(node)
121
- if option_enabled?(:UNSAFE)
122
- out(tagfilter(node.string_content))
123
- else
124
- out("<!-- raw HTML omitted -->")
125
- end
126
- end
127
-
128
- def emph(_)
129
- out("<em>", :children, "</em>")
130
- end
131
-
132
- def strong(node)
133
- if node.parent&.type == :strong
134
- out(:children)
135
- else
136
- out("<strong>", :children, "</strong>")
137
- end
138
- end
139
-
140
- def link(node)
141
- out('<a href="', node.url.nil? ? "" : escape_href(node.url), '"')
142
- out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
143
- out(">", :children, "</a>")
144
- end
145
-
146
- def image(node)
147
- out('<img src="', escape_href(node.url), '"')
148
- plain do
149
- out(' alt="', :children, '"')
150
- end
151
- out(' title="', escape_html(node.title), '"') if node.title && !node.title.empty?
152
- out(" />")
153
- end
154
-
155
- def text(node)
156
- out(escape_html(node.string_content))
157
- end
158
-
159
- def code(node)
160
- out("<code>")
161
- out(escape_html(node.string_content))
162
- out("</code>")
163
- end
164
-
165
- def linebreak(_node)
166
- out("<br />\n")
167
- end
168
-
169
- def softbreak(_)
170
- if option_enabled?(:HARDBREAKS)
171
- out("<br />\n")
172
- elsif option_enabled?(:NOBREAKS)
173
- out(" ")
174
- else
175
- out("\n")
176
- end
177
- end
178
-
179
- def table(node)
180
- @alignments = node.table_alignments
181
- @needs_close_tbody = false
182
- out("<table#{sourcepos(node)}>\n", :children)
183
- out("</tbody>\n") if @needs_close_tbody
184
- out("</table>\n")
185
- end
186
-
187
- def table_header(node)
188
- @column_index = 0
189
-
190
- @in_header = true
191
- out("<thead>\n<tr#{sourcepos(node)}>\n", :children, "</tr>\n</thead>\n")
192
- @in_header = false
193
- end
194
-
195
- def table_row(node)
196
- @column_index = 0
197
- if !@in_header && !@needs_close_tbody
198
- @needs_close_tbody = true
199
- out("<tbody>\n")
200
- end
201
- out("<tr#{sourcepos(node)}>\n", :children, "</tr>\n")
202
- end
203
-
204
- def table_cell(node)
205
- align = case @alignments[@column_index]
206
- when :left then ' align="left"'
207
- when :right then ' align="right"'
208
- when :center then ' align="center"'
209
- else; ""
210
- end
211
- out(@in_header ? "<th#{align}#{sourcepos(node)}>" : "<td#{align}#{sourcepos(node)}>", :children, @in_header ? "</th>\n" : "</td>\n")
212
- @column_index += 1
213
- end
214
-
215
- def strikethrough(_)
216
- out("<del>", :children, "</del>")
217
- end
218
-
219
- def footnote_reference(node)
220
- out("<sup class=\"footnote-ref\"><a href=\"#fn#{node.string_content}\" id=\"fnref#{node.string_content}\">#{node.string_content}</a></sup>")
221
- end
222
-
223
- def footnote_definition(_)
224
- unless @footnote_ix
225
- out("<section class=\"footnotes\">\n<ol>\n")
226
- @footnote_ix = 0
227
- end
228
-
229
- @footnote_ix += 1
230
- out("<li id=\"fn#{@footnote_ix}\">\n", :children)
231
- out("\n") if out_footnote_backref
232
- out("</li>\n")
233
- # </ol>
234
- # </section>
235
- end
236
-
237
- private
238
-
239
- def out_footnote_backref
240
- return false if @written_footnote_ix == @footnote_ix
241
-
242
- @written_footnote_ix = @footnote_ix
243
-
244
- out("<a href=\"#fnref#{@footnote_ix}\" class=\"footnote-backref\">↩</a>")
245
- true
246
- end
247
-
248
- def tasklist?(node)
249
- node.type_string == "tasklist"
250
- end
251
-
252
- def checked?(node)
253
- node.tasklist_item_checked?
254
- end
255
- end
256
- end