markly 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/bin/markly +94 -0
  3. data/ext/markly/arena.c +103 -0
  4. data/ext/markly/autolink.c +425 -0
  5. data/ext/markly/autolink.h +8 -0
  6. data/ext/markly/blocks.c +1585 -0
  7. data/ext/markly/buffer.c +278 -0
  8. data/ext/markly/buffer.h +116 -0
  9. data/ext/markly/case_fold_switch.inc +4327 -0
  10. data/ext/markly/chunk.h +135 -0
  11. data/ext/markly/cmark-gfm-core-extensions.h +54 -0
  12. data/ext/markly/cmark-gfm-extension_api.h +736 -0
  13. data/ext/markly/cmark-gfm-extensions_export.h +42 -0
  14. data/ext/markly/cmark-gfm.h +817 -0
  15. data/ext/markly/cmark-gfm_export.h +42 -0
  16. data/ext/markly/cmark-gfm_version.h +7 -0
  17. data/ext/markly/cmark.c +55 -0
  18. data/ext/markly/cmark_ctype.c +44 -0
  19. data/ext/markly/cmark_ctype.h +33 -0
  20. data/ext/markly/commonmark.c +519 -0
  21. data/ext/markly/config.h +76 -0
  22. data/ext/markly/core-extensions.c +27 -0
  23. data/ext/markly/entities.inc +2138 -0
  24. data/ext/markly/ext_scanners.c +1159 -0
  25. data/ext/markly/ext_scanners.h +24 -0
  26. data/ext/markly/extconf.rb +7 -0
  27. data/ext/markly/footnotes.c +40 -0
  28. data/ext/markly/footnotes.h +25 -0
  29. data/ext/markly/houdini.h +57 -0
  30. data/ext/markly/houdini_href_e.c +100 -0
  31. data/ext/markly/houdini_html_e.c +66 -0
  32. data/ext/markly/houdini_html_u.c +149 -0
  33. data/ext/markly/html.c +465 -0
  34. data/ext/markly/html.h +27 -0
  35. data/ext/markly/inlines.c +1633 -0
  36. data/ext/markly/inlines.h +29 -0
  37. data/ext/markly/iterator.c +159 -0
  38. data/ext/markly/iterator.h +26 -0
  39. data/ext/markly/latex.c +466 -0
  40. data/ext/markly/linked_list.c +37 -0
  41. data/ext/markly/man.c +278 -0
  42. data/ext/markly/map.c +122 -0
  43. data/ext/markly/map.h +41 -0
  44. data/ext/markly/markly.c +1226 -0
  45. data/ext/markly/markly.h +16 -0
  46. data/ext/markly/node.c +979 -0
  47. data/ext/markly/node.h +118 -0
  48. data/ext/markly/parser.h +58 -0
  49. data/ext/markly/plaintext.c +235 -0
  50. data/ext/markly/plugin.c +36 -0
  51. data/ext/markly/plugin.h +34 -0
  52. data/ext/markly/references.c +42 -0
  53. data/ext/markly/references.h +26 -0
  54. data/ext/markly/registry.c +63 -0
  55. data/ext/markly/registry.h +24 -0
  56. data/ext/markly/render.c +205 -0
  57. data/ext/markly/render.h +62 -0
  58. data/ext/markly/scanners.c +20382 -0
  59. data/ext/markly/scanners.h +62 -0
  60. data/ext/markly/scanners.re +326 -0
  61. data/ext/markly/strikethrough.c +167 -0
  62. data/ext/markly/strikethrough.h +9 -0
  63. data/ext/markly/syntax_extension.c +149 -0
  64. data/ext/markly/syntax_extension.h +34 -0
  65. data/ext/markly/table.c +803 -0
  66. data/ext/markly/table.h +12 -0
  67. data/ext/markly/tagfilter.c +60 -0
  68. data/ext/markly/tagfilter.h +8 -0
  69. data/ext/markly/tasklist.c +156 -0
  70. data/ext/markly/tasklist.h +8 -0
  71. data/ext/markly/utf8.c +317 -0
  72. data/ext/markly/utf8.h +35 -0
  73. data/ext/markly/xml.c +181 -0
  74. data/lib/markly.rb +43 -0
  75. data/lib/markly/flags.rb +37 -0
  76. data/lib/markly/markly.so +0 -0
  77. data/lib/markly/node.rb +70 -0
  78. data/lib/markly/node/inspect.rb +59 -0
  79. data/lib/markly/renderer.rb +133 -0
  80. data/lib/markly/renderer/html_renderer.rb +252 -0
  81. data/lib/markly/version.rb +5 -0
  82. metadata +211 -0
@@ -0,0 +1,118 @@
1
+ #ifndef CMARK_NODE_H
2
+ #define CMARK_NODE_H
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ #include <stdio.h>
9
+ #include <stdint.h>
10
+
11
+ #include "cmark-gfm.h"
12
+ #include "cmark-gfm-extension_api.h"
13
+ #include "buffer.h"
14
+ #include "chunk.h"
15
+
16
+ typedef struct {
17
+ cmark_list_type list_type;
18
+ int marker_offset;
19
+ int padding;
20
+ int start;
21
+ cmark_delim_type delimiter;
22
+ unsigned char bullet_char;
23
+ bool tight;
24
+ bool checked; // For task list extension
25
+ } cmark_list;
26
+
27
+ typedef struct {
28
+ cmark_chunk info;
29
+ cmark_chunk literal;
30
+ uint8_t fence_length;
31
+ uint8_t fence_offset;
32
+ unsigned char fence_char;
33
+ int8_t fenced;
34
+ } cmark_code;
35
+
36
+ typedef struct {
37
+ int level;
38
+ bool setext;
39
+ } cmark_heading;
40
+
41
+ typedef struct {
42
+ cmark_chunk url;
43
+ cmark_chunk title;
44
+ } cmark_link;
45
+
46
+ typedef struct {
47
+ cmark_chunk on_enter;
48
+ cmark_chunk on_exit;
49
+ } cmark_custom;
50
+
51
+ enum cmark_node__internal_flags {
52
+ CMARK_NODE__OPEN = (1 << 0),
53
+ CMARK_NODE__LAST_LINE_BLANK = (1 << 1),
54
+ CMARK_NODE__LAST_LINE_CHECKED = (1 << 2),
55
+ };
56
+
57
+ struct cmark_node {
58
+ cmark_strbuf content;
59
+
60
+ struct cmark_node *next;
61
+ struct cmark_node *prev;
62
+ struct cmark_node *parent;
63
+ struct cmark_node *first_child;
64
+ struct cmark_node *last_child;
65
+
66
+ void *user_data;
67
+ cmark_free_func user_data_free_func;
68
+
69
+ int start_line;
70
+ int start_column;
71
+ int end_line;
72
+ int end_column;
73
+ int internal_offset;
74
+ uint16_t type;
75
+ uint16_t flags;
76
+
77
+ cmark_syntax_extension *extension;
78
+
79
+ union {
80
+ cmark_chunk literal;
81
+ cmark_list list;
82
+ cmark_code code;
83
+ cmark_heading heading;
84
+ cmark_link link;
85
+ cmark_custom custom;
86
+ int html_block_type;
87
+ void *opaque;
88
+ } as;
89
+ };
90
+
91
+ static CMARK_INLINE cmark_mem *cmark_node_mem(cmark_node *node) {
92
+ return node->content.mem;
93
+ }
94
+ CMARK_GFM_EXPORT int cmark_node_check(cmark_node *node, FILE *out);
95
+
96
+ static CMARK_INLINE bool CMARK_NODE_TYPE_BLOCK_P(cmark_node_type node_type) {
97
+ return (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_BLOCK;
98
+ }
99
+
100
+ static CMARK_INLINE bool CMARK_NODE_BLOCK_P(cmark_node *node) {
101
+ return node != NULL && CMARK_NODE_TYPE_BLOCK_P((cmark_node_type) node->type);
102
+ }
103
+
104
+ static CMARK_INLINE bool CMARK_NODE_TYPE_INLINE_P(cmark_node_type node_type) {
105
+ return (node_type & CMARK_NODE_TYPE_MASK) == CMARK_NODE_TYPE_INLINE;
106
+ }
107
+
108
+ static CMARK_INLINE bool CMARK_NODE_INLINE_P(cmark_node *node) {
109
+ return node != NULL && CMARK_NODE_TYPE_INLINE_P((cmark_node_type) node->type);
110
+ }
111
+
112
+ CMARK_GFM_EXPORT bool cmark_node_can_contain_type(cmark_node *node, cmark_node_type child_type);
113
+
114
+ #ifdef __cplusplus
115
+ }
116
+ #endif
117
+
118
+ #endif
@@ -0,0 +1,58 @@
1
+ #ifndef CMARK_PARSER_H
2
+ #define CMARK_PARSER_H
3
+
4
+ #include <stdio.h>
5
+ #include "references.h"
6
+ #include "node.h"
7
+ #include "buffer.h"
8
+
9
+ #ifdef __cplusplus
10
+ extern "C" {
11
+ #endif
12
+
13
+ #define MAX_LINK_LABEL_LENGTH 1000
14
+
15
+ struct cmark_parser {
16
+ struct cmark_mem *mem;
17
+ /* A hashtable of urls in the current document for cross-references */
18
+ struct cmark_map *refmap;
19
+ /* The root node of the parser, always a CMARK_NODE_DOCUMENT */
20
+ struct cmark_node *root;
21
+ /* The last open block after a line is fully processed */
22
+ struct cmark_node *current;
23
+ /* See the documentation for cmark_parser_get_line_number() in cmark.h */
24
+ int line_number;
25
+ /* See the documentation for cmark_parser_get_offset() in cmark.h */
26
+ bufsize_t offset;
27
+ /* See the documentation for cmark_parser_get_column() in cmark.h */
28
+ bufsize_t column;
29
+ /* See the documentation for cmark_parser_get_first_nonspace() in cmark.h */
30
+ bufsize_t first_nonspace;
31
+ /* See the documentation for cmark_parser_get_first_nonspace_column() in cmark.h */
32
+ bufsize_t first_nonspace_column;
33
+ bufsize_t thematic_break_kill_pos;
34
+ /* See the documentation for cmark_parser_get_indent() in cmark.h */
35
+ int indent;
36
+ /* See the documentation for cmark_parser_is_blank() in cmark.h */
37
+ bool blank;
38
+ /* See the documentation for cmark_parser_has_partially_consumed_tab() in cmark.h */
39
+ bool partially_consumed_tab;
40
+ /* Contains the currently processed line */
41
+ cmark_strbuf curline;
42
+ /* See the documentation for cmark_parser_get_last_line_length() in cmark.h */
43
+ bufsize_t last_line_length;
44
+ /* FIXME: not sure about the difference with curline */
45
+ cmark_strbuf linebuf;
46
+ /* Options set by the user, see the Options section in cmark.h */
47
+ int options;
48
+ bool last_buffer_ended_with_cr;
49
+ cmark_llist *syntax_extensions;
50
+ cmark_llist *inline_syntax_extensions;
51
+ cmark_ispunct_func backslash_ispunct;
52
+ };
53
+
54
+ #ifdef __cplusplus
55
+ }
56
+ #endif
57
+
58
+ #endif
@@ -0,0 +1,235 @@
1
+ #include "node.h"
2
+ #include "syntax_extension.h"
3
+ #include "render.h"
4
+
5
+ #define OUT(s, wrap, escaping) renderer->out(renderer, node, s, wrap, escaping)
6
+ #define LIT(s) renderer->out(renderer, node, s, false, LITERAL)
7
+ #define CR() renderer->cr(renderer)
8
+ #define BLANKLINE() renderer->blankline(renderer)
9
+ #define LISTMARKER_SIZE 20
10
+
11
+ // Functions to convert cmark_nodes to plain text strings.
12
+
13
+ static CMARK_INLINE void outc(cmark_renderer *renderer, cmark_node *node,
14
+ cmark_escaping escape,
15
+ int32_t c, unsigned char nextc) {
16
+ cmark_render_code_point(renderer, c);
17
+ }
18
+
19
+ // if node is a block node, returns node.
20
+ // otherwise returns first block-level node that is an ancestor of node.
21
+ // if there is no block-level ancestor, returns NULL.
22
+ static cmark_node *get_containing_block(cmark_node *node) {
23
+ while (node) {
24
+ if (CMARK_NODE_BLOCK_P(node)) {
25
+ return node;
26
+ } else {
27
+ node = node->parent;
28
+ }
29
+ }
30
+ return NULL;
31
+ }
32
+
33
+ static int S_render_node(cmark_renderer *renderer, cmark_node *node,
34
+ cmark_event_type ev_type, int options) {
35
+ cmark_node *tmp;
36
+ int list_number;
37
+ cmark_delim_type list_delim;
38
+ int i;
39
+ bool entering = (ev_type == CMARK_EVENT_ENTER);
40
+ char listmarker[LISTMARKER_SIZE];
41
+ bool first_in_list_item;
42
+ bufsize_t marker_width;
43
+ bool allow_wrap = renderer->width > 0 && !(CMARK_OPT_NOBREAKS & options) &&
44
+ !(CMARK_OPT_HARDBREAKS & options);
45
+
46
+ // Don't adjust tight list status til we've started the list.
47
+ // Otherwise we loose the blank line between a paragraph and
48
+ // a following list.
49
+ if (!(node->type == CMARK_NODE_ITEM && node->prev == NULL && entering)) {
50
+ tmp = get_containing_block(node);
51
+ renderer->in_tight_list_item =
52
+ tmp && // tmp might be NULL if there is no containing block
53
+ ((tmp->type == CMARK_NODE_ITEM &&
54
+ cmark_node_get_list_tight(tmp->parent)) ||
55
+ (tmp && tmp->parent && tmp->parent->type == CMARK_NODE_ITEM &&
56
+ cmark_node_get_list_tight(tmp->parent->parent)));
57
+ }
58
+
59
+ if (node->extension && node->extension->plaintext_render_func) {
60
+ node->extension->plaintext_render_func(node->extension, renderer, node, ev_type, options);
61
+ return 1;
62
+ }
63
+
64
+ switch (node->type) {
65
+ case CMARK_NODE_DOCUMENT:
66
+ break;
67
+
68
+ case CMARK_NODE_BLOCK_QUOTE:
69
+ break;
70
+
71
+ case CMARK_NODE_LIST:
72
+ if (!entering && node->next && (node->next->type == CMARK_NODE_CODE_BLOCK ||
73
+ node->next->type == CMARK_NODE_LIST)) {
74
+ CR();
75
+ }
76
+ break;
77
+
78
+ case CMARK_NODE_ITEM:
79
+ if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
80
+ marker_width = 4;
81
+ } else {
82
+ list_number = cmark_node_get_list_start(node->parent);
83
+ list_delim = cmark_node_get_list_delim(node->parent);
84
+ tmp = node;
85
+ while (tmp->prev) {
86
+ tmp = tmp->prev;
87
+ list_number += 1;
88
+ }
89
+ // we ensure a width of at least 4 so
90
+ // we get nice transition from single digits
91
+ // to double
92
+ snprintf(listmarker, LISTMARKER_SIZE, "%d%s%s", list_number,
93
+ list_delim == CMARK_PAREN_DELIM ? ")" : ".",
94
+ list_number < 10 ? " " : " ");
95
+ marker_width = (bufsize_t)strlen(listmarker);
96
+ }
97
+ if (entering) {
98
+ if (cmark_node_get_list_type(node->parent) == CMARK_BULLET_LIST) {
99
+ LIT(" - ");
100
+ renderer->begin_content = true;
101
+ } else {
102
+ LIT(listmarker);
103
+ renderer->begin_content = true;
104
+ }
105
+ for (i = marker_width; i--;) {
106
+ cmark_strbuf_putc(renderer->prefix, ' ');
107
+ }
108
+ } else {
109
+ cmark_strbuf_truncate(renderer->prefix,
110
+ renderer->prefix->size - marker_width);
111
+ CR();
112
+ }
113
+ break;
114
+
115
+ case CMARK_NODE_HEADING:
116
+ if (entering) {
117
+ renderer->begin_content = true;
118
+ renderer->no_linebreaks = true;
119
+ } else {
120
+ renderer->no_linebreaks = false;
121
+ BLANKLINE();
122
+ }
123
+ break;
124
+
125
+ case CMARK_NODE_CODE_BLOCK:
126
+ first_in_list_item = node->prev == NULL && node->parent &&
127
+ node->parent->type == CMARK_NODE_ITEM;
128
+
129
+ if (!first_in_list_item) {
130
+ BLANKLINE();
131
+ }
132
+ OUT(cmark_node_get_literal(node), false, LITERAL);
133
+ BLANKLINE();
134
+ break;
135
+
136
+ case CMARK_NODE_HTML_BLOCK:
137
+ break;
138
+
139
+ case CMARK_NODE_CUSTOM_BLOCK:
140
+ break;
141
+
142
+ case CMARK_NODE_THEMATIC_BREAK:
143
+ BLANKLINE();
144
+ break;
145
+
146
+ case CMARK_NODE_PARAGRAPH:
147
+ if (!entering) {
148
+ BLANKLINE();
149
+ }
150
+ break;
151
+
152
+ case CMARK_NODE_TEXT:
153
+ OUT(cmark_node_get_literal(node), allow_wrap, NORMAL);
154
+ break;
155
+
156
+ case CMARK_NODE_LINEBREAK:
157
+ CR();
158
+ break;
159
+
160
+ case CMARK_NODE_SOFTBREAK:
161
+ if (CMARK_OPT_HARDBREAKS & options) {
162
+ CR();
163
+ } else if (!renderer->no_linebreaks && renderer->width == 0 &&
164
+ !(CMARK_OPT_HARDBREAKS & options) &&
165
+ !(CMARK_OPT_NOBREAKS & options)) {
166
+ CR();
167
+ } else {
168
+ OUT(" ", allow_wrap, LITERAL);
169
+ }
170
+ break;
171
+
172
+ case CMARK_NODE_CODE:
173
+ OUT(cmark_node_get_literal(node), allow_wrap, LITERAL);
174
+ break;
175
+
176
+ case CMARK_NODE_HTML_INLINE:
177
+ break;
178
+
179
+ case CMARK_NODE_CUSTOM_INLINE:
180
+ break;
181
+
182
+ case CMARK_NODE_STRONG:
183
+ break;
184
+
185
+ case CMARK_NODE_EMPH:
186
+ break;
187
+
188
+ case CMARK_NODE_LINK:
189
+ break;
190
+
191
+ case CMARK_NODE_IMAGE:
192
+ break;
193
+
194
+ case CMARK_NODE_FOOTNOTE_REFERENCE:
195
+ if (entering) {
196
+ LIT("[^");
197
+ OUT(cmark_chunk_to_cstr(renderer->mem, &node->as.literal), false, LITERAL);
198
+ LIT("]");
199
+ }
200
+ break;
201
+
202
+ case CMARK_NODE_FOOTNOTE_DEFINITION:
203
+ if (entering) {
204
+ renderer->footnote_ix += 1;
205
+ LIT("[^");
206
+ char n[32];
207
+ snprintf(n, sizeof(n), "%d", renderer->footnote_ix);
208
+ OUT(n, false, LITERAL);
209
+ LIT("]: ");
210
+
211
+ cmark_strbuf_puts(renderer->prefix, " ");
212
+ } else {
213
+ cmark_strbuf_truncate(renderer->prefix, renderer->prefix->size - 4);
214
+ }
215
+ break;
216
+ default:
217
+ assert(false);
218
+ break;
219
+ }
220
+
221
+ return 1;
222
+ }
223
+
224
+ char *cmark_render_plaintext(cmark_node *root, int options, int width) {
225
+ return cmark_render_plaintext_with_mem(root, options, width, cmark_node_mem(root));
226
+ }
227
+
228
+ char *cmark_render_plaintext_with_mem(cmark_node *root, int options, int width, cmark_mem *mem) {
229
+ if (options & CMARK_OPT_HARDBREAKS) {
230
+ // disable breaking on width, since it has
231
+ // a different meaning with OPT_HARDBREAKS
232
+ width = 0;
233
+ }
234
+ return cmark_render(mem, root, options, width, outc, S_render_node);
235
+ }
@@ -0,0 +1,36 @@
1
+ #include <stdlib.h>
2
+
3
+ #include "plugin.h"
4
+
5
+ extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
6
+
7
+ int cmark_plugin_register_syntax_extension(cmark_plugin * plugin,
8
+ cmark_syntax_extension * extension) {
9
+ plugin->syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, plugin->syntax_extensions, extension);
10
+ return 1;
11
+ }
12
+
13
+ cmark_plugin *
14
+ cmark_plugin_new(void) {
15
+ cmark_plugin *res = (cmark_plugin *) CMARK_DEFAULT_MEM_ALLOCATOR.calloc(1, sizeof(cmark_plugin));
16
+
17
+ res->syntax_extensions = NULL;
18
+
19
+ return res;
20
+ }
21
+
22
+ void
23
+ cmark_plugin_free(cmark_plugin *plugin) {
24
+ cmark_llist_free_full(&CMARK_DEFAULT_MEM_ALLOCATOR,
25
+ plugin->syntax_extensions,
26
+ (cmark_free_func) cmark_syntax_extension_free);
27
+ CMARK_DEFAULT_MEM_ALLOCATOR.free(plugin);
28
+ }
29
+
30
+ cmark_llist *
31
+ cmark_plugin_steal_syntax_extensions(cmark_plugin *plugin) {
32
+ cmark_llist *res = plugin->syntax_extensions;
33
+
34
+ plugin->syntax_extensions = NULL;
35
+ return res;
36
+ }