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,34 @@
1
+ #ifndef CMARK_PLUGIN_H
2
+ #define CMARK_PLUGIN_H
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ #include "cmark-gfm.h"
9
+ #include "cmark-gfm-extension_api.h"
10
+
11
+ /**
12
+ * cmark_plugin:
13
+ *
14
+ * A plugin structure, which should be filled by plugin's
15
+ * init functions.
16
+ */
17
+ struct cmark_plugin {
18
+ cmark_llist *syntax_extensions;
19
+ };
20
+
21
+ cmark_llist *
22
+ cmark_plugin_steal_syntax_extensions(cmark_plugin *plugin);
23
+
24
+ cmark_plugin *
25
+ cmark_plugin_new(void);
26
+
27
+ void
28
+ cmark_plugin_free(cmark_plugin *plugin);
29
+
30
+ #ifdef __cplusplus
31
+ }
32
+ #endif
33
+
34
+ #endif
@@ -0,0 +1,42 @@
1
+ #include "cmark-gfm.h"
2
+ #include "parser.h"
3
+ #include "references.h"
4
+ #include "inlines.h"
5
+ #include "chunk.h"
6
+
7
+ static void reference_free(cmark_map *map, cmark_map_entry *_ref) {
8
+ cmark_reference *ref = (cmark_reference *)_ref;
9
+ cmark_mem *mem = map->mem;
10
+ if (ref != NULL) {
11
+ mem->free(ref->entry.label);
12
+ cmark_chunk_free(mem, &ref->url);
13
+ cmark_chunk_free(mem, &ref->title);
14
+ mem->free(ref);
15
+ }
16
+ }
17
+
18
+ void cmark_reference_create(cmark_map *map, cmark_chunk *label,
19
+ cmark_chunk *url, cmark_chunk *title) {
20
+ cmark_reference *ref;
21
+ unsigned char *reflabel = normalize_map_label(map->mem, label);
22
+
23
+ /* empty reference name, or composed from only whitespace */
24
+ if (reflabel == NULL)
25
+ return;
26
+
27
+ assert(map->sorted == NULL);
28
+
29
+ ref = (cmark_reference *)map->mem->calloc(1, sizeof(*ref));
30
+ ref->entry.label = reflabel;
31
+ ref->url = cmark_clean_url(map->mem, url);
32
+ ref->title = cmark_clean_title(map->mem, title);
33
+ ref->entry.age = map->size;
34
+ ref->entry.next = map->refs;
35
+
36
+ map->refs = (cmark_map_entry *)ref;
37
+ map->size++;
38
+ }
39
+
40
+ cmark_map *cmark_reference_map_new(cmark_mem *mem) {
41
+ return cmark_map_new(mem, reference_free);
42
+ }
@@ -0,0 +1,26 @@
1
+ #ifndef CMARK_REFERENCES_H
2
+ #define CMARK_REFERENCES_H
3
+
4
+ #include "map.h"
5
+
6
+ #ifdef __cplusplus
7
+ extern "C" {
8
+ #endif
9
+
10
+ struct cmark_reference {
11
+ cmark_map_entry entry;
12
+ cmark_chunk url;
13
+ cmark_chunk title;
14
+ };
15
+
16
+ typedef struct cmark_reference cmark_reference;
17
+
18
+ void cmark_reference_create(cmark_map *map, cmark_chunk *label,
19
+ cmark_chunk *url, cmark_chunk *title);
20
+ cmark_map *cmark_reference_map_new(cmark_mem *mem);
21
+
22
+ #ifdef __cplusplus
23
+ }
24
+ #endif
25
+
26
+ #endif
@@ -0,0 +1,63 @@
1
+ #include <stdint.h>
2
+ #include <stdlib.h>
3
+ #include <string.h>
4
+
5
+ #include "config.h"
6
+ #include "cmark-gfm.h"
7
+ #include "syntax_extension.h"
8
+ #include "registry.h"
9
+ #include "plugin.h"
10
+
11
+ extern cmark_mem CMARK_DEFAULT_MEM_ALLOCATOR;
12
+
13
+ static cmark_llist *syntax_extensions = NULL;
14
+
15
+ void cmark_register_plugin(cmark_plugin_init_func reg_fn) {
16
+ cmark_plugin *plugin = cmark_plugin_new();
17
+
18
+ if (!reg_fn(plugin)) {
19
+ cmark_plugin_free(plugin);
20
+ return;
21
+ }
22
+
23
+ cmark_llist *syntax_extensions_list = cmark_plugin_steal_syntax_extensions(plugin),
24
+ *it;
25
+
26
+ for (it = syntax_extensions_list; it; it = it->next) {
27
+ syntax_extensions = cmark_llist_append(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions, it->data);
28
+ }
29
+
30
+ cmark_llist_free(&CMARK_DEFAULT_MEM_ALLOCATOR, syntax_extensions_list);
31
+ cmark_plugin_free(plugin);
32
+ }
33
+
34
+ void cmark_release_plugins(void) {
35
+ if (syntax_extensions) {
36
+ cmark_llist_free_full(
37
+ &CMARK_DEFAULT_MEM_ALLOCATOR,
38
+ syntax_extensions,
39
+ (cmark_free_func) cmark_syntax_extension_free);
40
+ syntax_extensions = NULL;
41
+ }
42
+ }
43
+
44
+ cmark_llist *cmark_list_syntax_extensions(cmark_mem *mem) {
45
+ cmark_llist *it;
46
+ cmark_llist *res = NULL;
47
+
48
+ for (it = syntax_extensions; it; it = it->next) {
49
+ res = cmark_llist_append(mem, res, it->data);
50
+ }
51
+ return res;
52
+ }
53
+
54
+ cmark_syntax_extension *cmark_find_syntax_extension(const char *name) {
55
+ cmark_llist *tmp;
56
+
57
+ for (tmp = syntax_extensions; tmp; tmp = tmp->next) {
58
+ cmark_syntax_extension *ext = (cmark_syntax_extension *) tmp->data;
59
+ if (!strcmp(ext->name, name))
60
+ return ext;
61
+ }
62
+ return NULL;
63
+ }
@@ -0,0 +1,24 @@
1
+ #ifndef CMARK_REGISTRY_H
2
+ #define CMARK_REGISTRY_H
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ #include "cmark-gfm.h"
9
+ #include "plugin.h"
10
+
11
+ CMARK_GFM_EXPORT
12
+ void cmark_register_plugin(cmark_plugin_init_func reg_fn);
13
+
14
+ CMARK_GFM_EXPORT
15
+ void cmark_release_plugins(void);
16
+
17
+ CMARK_GFM_EXPORT
18
+ cmark_llist *cmark_list_syntax_extensions(cmark_mem *mem);
19
+
20
+ #ifdef __cplusplus
21
+ }
22
+ #endif
23
+
24
+ #endif
@@ -0,0 +1,205 @@
1
+ #include <stdlib.h>
2
+ #include "buffer.h"
3
+ #include "chunk.h"
4
+ #include "cmark-gfm.h"
5
+ #include "utf8.h"
6
+ #include "render.h"
7
+ #include "node.h"
8
+ #include "syntax_extension.h"
9
+
10
+ static CMARK_INLINE void S_cr(cmark_renderer *renderer) {
11
+ if (renderer->need_cr < 1) {
12
+ renderer->need_cr = 1;
13
+ }
14
+ }
15
+
16
+ static CMARK_INLINE void S_blankline(cmark_renderer *renderer) {
17
+ if (renderer->need_cr < 2) {
18
+ renderer->need_cr = 2;
19
+ }
20
+ }
21
+
22
+ static void S_out(cmark_renderer *renderer, cmark_node *node,
23
+ const char *source, bool wrap,
24
+ cmark_escaping escape) {
25
+ int length = (int)strlen(source);
26
+ unsigned char nextc;
27
+ int32_t c;
28
+ int i = 0;
29
+ int last_nonspace;
30
+ int len;
31
+ cmark_chunk remainder = cmark_chunk_literal("");
32
+ int k = renderer->buffer->size - 1;
33
+
34
+ cmark_syntax_extension *ext = NULL;
35
+ cmark_node *n = node;
36
+ while (n && !ext) {
37
+ ext = n->extension;
38
+ if (!ext)
39
+ n = n->parent;
40
+ }
41
+ if (ext && !ext->commonmark_escape_func)
42
+ ext = NULL;
43
+
44
+ wrap = wrap && !renderer->no_linebreaks;
45
+
46
+ if (renderer->in_tight_list_item && renderer->need_cr > 1) {
47
+ renderer->need_cr = 1;
48
+ }
49
+ while (renderer->need_cr) {
50
+ if (k < 0 || renderer->buffer->ptr[k] == '\n') {
51
+ k -= 1;
52
+ } else {
53
+ cmark_strbuf_putc(renderer->buffer, '\n');
54
+ if (renderer->need_cr > 1) {
55
+ cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
56
+ renderer->prefix->size);
57
+ }
58
+ }
59
+ renderer->column = 0;
60
+ renderer->last_breakable = 0;
61
+ renderer->begin_line = true;
62
+ renderer->begin_content = true;
63
+ renderer->need_cr -= 1;
64
+ }
65
+
66
+ while (i < length) {
67
+ if (renderer->begin_line) {
68
+ cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
69
+ renderer->prefix->size);
70
+ // note: this assumes prefix is ascii:
71
+ renderer->column = renderer->prefix->size;
72
+ }
73
+
74
+ len = cmark_utf8proc_iterate((const uint8_t *)source + i, length - i, &c);
75
+ if (len == -1) { // error condition
76
+ return; // return without rendering rest of string
77
+ }
78
+
79
+ if (ext && ext->commonmark_escape_func(ext, node, c))
80
+ cmark_strbuf_putc(renderer->buffer, '\\');
81
+
82
+ nextc = source[i + len];
83
+ if (c == 32 && wrap) {
84
+ if (!renderer->begin_line) {
85
+ last_nonspace = renderer->buffer->size;
86
+ cmark_strbuf_putc(renderer->buffer, ' ');
87
+ renderer->column += 1;
88
+ renderer->begin_line = false;
89
+ renderer->begin_content = false;
90
+ // skip following spaces
91
+ while (source[i + 1] == ' ') {
92
+ i++;
93
+ }
94
+ // We don't allow breaks that make a digit the first character
95
+ // because this causes problems with commonmark output.
96
+ if (!cmark_isdigit(source[i + 1])) {
97
+ renderer->last_breakable = last_nonspace;
98
+ }
99
+ }
100
+
101
+ } else if (escape == LITERAL) {
102
+ if (c == 10) {
103
+ cmark_strbuf_putc(renderer->buffer, '\n');
104
+ renderer->column = 0;
105
+ renderer->begin_line = true;
106
+ renderer->begin_content = true;
107
+ renderer->last_breakable = 0;
108
+ } else {
109
+ cmark_render_code_point(renderer, c);
110
+ renderer->begin_line = false;
111
+ // we don't set 'begin_content' to false til we've
112
+ // finished parsing a digit. Reason: in commonmark
113
+ // we need to escape a potential list marker after
114
+ // a digit:
115
+ renderer->begin_content =
116
+ renderer->begin_content && cmark_isdigit((char)c) == 1;
117
+ }
118
+ } else {
119
+ (renderer->outc)(renderer, node, escape, c, nextc);
120
+ renderer->begin_line = false;
121
+ renderer->begin_content =
122
+ renderer->begin_content && cmark_isdigit((char)c) == 1;
123
+ }
124
+
125
+ // If adding the character went beyond width, look for an
126
+ // earlier place where the line could be broken:
127
+ if (renderer->width > 0 && renderer->column > renderer->width &&
128
+ !renderer->begin_line && renderer->last_breakable > 0) {
129
+
130
+ // copy from last_breakable to remainder
131
+ cmark_chunk_set_cstr(renderer->mem, &remainder,
132
+ (char *)renderer->buffer->ptr +
133
+ renderer->last_breakable + 1);
134
+ // truncate at last_breakable
135
+ cmark_strbuf_truncate(renderer->buffer, renderer->last_breakable);
136
+ // add newline, prefix, and remainder
137
+ cmark_strbuf_putc(renderer->buffer, '\n');
138
+ cmark_strbuf_put(renderer->buffer, renderer->prefix->ptr,
139
+ renderer->prefix->size);
140
+ cmark_strbuf_put(renderer->buffer, remainder.data, remainder.len);
141
+ renderer->column = renderer->prefix->size + remainder.len;
142
+ cmark_chunk_free(renderer->mem, &remainder);
143
+ renderer->last_breakable = 0;
144
+ renderer->begin_line = false;
145
+ renderer->begin_content = false;
146
+ }
147
+
148
+ i += len;
149
+ }
150
+ }
151
+
152
+ // Assumes no newlines, assumes ascii content:
153
+ void cmark_render_ascii(cmark_renderer *renderer, const char *s) {
154
+ int origsize = renderer->buffer->size;
155
+ cmark_strbuf_puts(renderer->buffer, s);
156
+ renderer->column += renderer->buffer->size - origsize;
157
+ }
158
+
159
+ void cmark_render_code_point(cmark_renderer *renderer, uint32_t c) {
160
+ cmark_utf8proc_encode_char(c, renderer->buffer);
161
+ renderer->column += 1;
162
+ }
163
+
164
+ char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
165
+ void (*outc)(cmark_renderer *, cmark_node *,
166
+ cmark_escaping, int32_t,
167
+ unsigned char),
168
+ int (*render_node)(cmark_renderer *renderer,
169
+ cmark_node *node,
170
+ cmark_event_type ev_type, int options)) {
171
+ cmark_strbuf pref = CMARK_BUF_INIT(mem);
172
+ cmark_strbuf buf = CMARK_BUF_INIT(mem);
173
+ cmark_node *cur;
174
+ cmark_event_type ev_type;
175
+ char *result;
176
+ cmark_iter *iter = cmark_iter_new(root);
177
+
178
+ cmark_renderer renderer = {mem, &buf, &pref, 0, width,
179
+ 0, 0, true, true, false,
180
+ false, outc, S_cr, S_blankline, S_out,
181
+ 0};
182
+
183
+ while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
184
+ cur = cmark_iter_get_node(iter);
185
+ if (!render_node(&renderer, cur, ev_type, options)) {
186
+ // a false value causes us to skip processing
187
+ // the node's contents. this is used for
188
+ // autolinks.
189
+ cmark_iter_reset(iter, cur, CMARK_EVENT_EXIT);
190
+ }
191
+ }
192
+
193
+ // ensure final newline
194
+ if (renderer.buffer->size == 0 || renderer.buffer->ptr[renderer.buffer->size - 1] != '\n') {
195
+ cmark_strbuf_putc(renderer.buffer, '\n');
196
+ }
197
+
198
+ result = (char *)cmark_strbuf_detach(renderer.buffer);
199
+
200
+ cmark_iter_free(iter);
201
+ cmark_strbuf_free(renderer.prefix);
202
+ cmark_strbuf_free(renderer.buffer);
203
+
204
+ return result;
205
+ }
@@ -0,0 +1,62 @@
1
+ #ifndef CMARK_RENDER_H
2
+ #define CMARK_RENDER_H
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ #include <stdlib.h>
9
+ #include "buffer.h"
10
+ #include "chunk.h"
11
+
12
+ typedef enum { LITERAL, NORMAL, TITLE, URL } cmark_escaping;
13
+
14
+ struct cmark_renderer {
15
+ cmark_mem *mem;
16
+ cmark_strbuf *buffer;
17
+ cmark_strbuf *prefix;
18
+ int column;
19
+ int width;
20
+ int need_cr;
21
+ bufsize_t last_breakable;
22
+ bool begin_line;
23
+ bool begin_content;
24
+ bool no_linebreaks;
25
+ bool in_tight_list_item;
26
+ void (*outc)(struct cmark_renderer *, cmark_node *, cmark_escaping, int32_t, unsigned char);
27
+ void (*cr)(struct cmark_renderer *);
28
+ void (*blankline)(struct cmark_renderer *);
29
+ void (*out)(struct cmark_renderer *, cmark_node *, const char *, bool, cmark_escaping);
30
+ unsigned int footnote_ix;
31
+ };
32
+
33
+ typedef struct cmark_renderer cmark_renderer;
34
+
35
+ struct cmark_html_renderer {
36
+ cmark_strbuf *html;
37
+ cmark_node *plain;
38
+ cmark_llist *filter_extensions;
39
+ unsigned int footnote_ix;
40
+ unsigned int written_footnote_ix;
41
+ void *opaque;
42
+ };
43
+
44
+ typedef struct cmark_html_renderer cmark_html_renderer;
45
+
46
+ void cmark_render_ascii(cmark_renderer *renderer, const char *s);
47
+
48
+ void cmark_render_code_point(cmark_renderer *renderer, uint32_t c);
49
+
50
+ char *cmark_render(cmark_mem *mem, cmark_node *root, int options, int width,
51
+ void (*outc)(cmark_renderer *, cmark_node *,
52
+ cmark_escaping, int32_t,
53
+ unsigned char),
54
+ int (*render_node)(cmark_renderer *renderer,
55
+ cmark_node *node,
56
+ cmark_event_type ev_type, int options));
57
+
58
+ #ifdef __cplusplus
59
+ }
60
+ #endif
61
+
62
+ #endif