github-markdown-jekyll 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,51 @@
1
+ /*
2
+ * Copyright (c) 2011, Vicent Marti
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #ifndef UPSKIRT_AUTOLINK_H
18
+ #define UPSKIRT_AUTOLINK_H
19
+
20
+ #include "buffer.h"
21
+
22
+ #ifdef __cplusplus
23
+ extern "C" {
24
+ #endif
25
+
26
+ enum {
27
+ SD_AUTOLINK_SHORT_DOMAINS = (1 << 0),
28
+ };
29
+
30
+ int
31
+ sd_autolink_issafe(const uint8_t *link, size_t link_len);
32
+
33
+ size_t
34
+ sd_autolink__www(size_t *rewind_p, struct buf *link,
35
+ uint8_t *data, size_t offset, size_t size, unsigned int flags);
36
+
37
+ size_t
38
+ sd_autolink__email(size_t *rewind_p, struct buf *link,
39
+ uint8_t *data, size_t offset, size_t size, unsigned int flags);
40
+
41
+ size_t
42
+ sd_autolink__url(size_t *rewind_p, struct buf *link,
43
+ uint8_t *data, size_t offset, size_t size, unsigned int flags);
44
+
45
+ #ifdef __cplusplus
46
+ }
47
+ #endif
48
+
49
+ #endif
50
+
51
+ /* vim: set filetype=c: */
@@ -0,0 +1,225 @@
1
+ /*
2
+ * Copyright (c) 2008, Natacha Porté
3
+ * Copyright (c) 2011, Vicent Martí
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+
18
+ #define BUFFER_MAX_ALLOC_SIZE (1024 * 1024 * 16) //16mb
19
+
20
+ #include "buffer.h"
21
+
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+ #include <assert.h>
26
+
27
+ /* MSVC compat */
28
+ #if defined(_MSC_VER)
29
+ # define _buf_vsnprintf _vsnprintf
30
+ #else
31
+ # define _buf_vsnprintf vsnprintf
32
+ #endif
33
+
34
+ int
35
+ bufprefix(const struct buf *buf, const char *prefix)
36
+ {
37
+ size_t i;
38
+ assert(buf && buf->unit);
39
+
40
+ for (i = 0; i < buf->size; ++i) {
41
+ if (prefix[i] == 0)
42
+ return 0;
43
+
44
+ if (buf->data[i] != prefix[i])
45
+ return buf->data[i] - prefix[i];
46
+ }
47
+
48
+ return 0;
49
+ }
50
+
51
+ /* bufgrow: increasing the allocated size to the given value */
52
+ int
53
+ bufgrow(struct buf *buf, size_t neosz)
54
+ {
55
+ size_t neoasz;
56
+ void *neodata;
57
+
58
+ assert(buf && buf->unit);
59
+
60
+ if (neosz > BUFFER_MAX_ALLOC_SIZE)
61
+ return BUF_ENOMEM;
62
+
63
+ if (buf->asize >= neosz)
64
+ return BUF_OK;
65
+
66
+ neoasz = buf->asize + buf->unit;
67
+ while (neoasz < neosz)
68
+ neoasz += buf->unit;
69
+
70
+ neodata = realloc(buf->data, neoasz);
71
+ if (!neodata)
72
+ return BUF_ENOMEM;
73
+
74
+ buf->data = neodata;
75
+ buf->asize = neoasz;
76
+ return BUF_OK;
77
+ }
78
+
79
+
80
+ /* bufnew: allocation of a new buffer */
81
+ struct buf *
82
+ bufnew(size_t unit)
83
+ {
84
+ struct buf *ret;
85
+ ret = malloc(sizeof (struct buf));
86
+
87
+ if (ret) {
88
+ ret->data = 0;
89
+ ret->size = ret->asize = 0;
90
+ ret->unit = unit;
91
+ }
92
+ return ret;
93
+ }
94
+
95
+ /* bufnullterm: NULL-termination of the string array */
96
+ const char *
97
+ bufcstr(struct buf *buf)
98
+ {
99
+ assert(buf && buf->unit);
100
+
101
+ if (buf->size < buf->asize && buf->data[buf->size] == 0)
102
+ return (char *)buf->data;
103
+
104
+ if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1) == 0) {
105
+ buf->data[buf->size] = 0;
106
+ return (char *)buf->data;
107
+ }
108
+
109
+ return NULL;
110
+ }
111
+
112
+ /* bufprintf: formatted printing to a buffer */
113
+ void
114
+ bufprintf(struct buf *buf, const char *fmt, ...)
115
+ {
116
+ va_list ap;
117
+ int n;
118
+
119
+ assert(buf && buf->unit);
120
+
121
+ if (buf->size >= buf->asize && bufgrow(buf, buf->size + 1) < 0)
122
+ return;
123
+
124
+ va_start(ap, fmt);
125
+ n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
126
+ va_end(ap);
127
+
128
+ if (n < 0) {
129
+ #ifdef _MSC_VER
130
+ va_start(ap, fmt);
131
+ n = _vscprintf(fmt, ap);
132
+ va_end(ap);
133
+ #else
134
+ return;
135
+ #endif
136
+ }
137
+
138
+ if ((size_t)n >= buf->asize - buf->size) {
139
+ if (bufgrow(buf, buf->size + n + 1) < 0)
140
+ return;
141
+
142
+ va_start(ap, fmt);
143
+ n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap);
144
+ va_end(ap);
145
+ }
146
+
147
+ if (n < 0)
148
+ return;
149
+
150
+ buf->size += n;
151
+ }
152
+
153
+ /* bufput: appends raw data to a buffer */
154
+ void
155
+ bufput(struct buf *buf, const void *data, size_t len)
156
+ {
157
+ assert(buf && buf->unit);
158
+
159
+ if (buf->size + len > buf->asize && bufgrow(buf, buf->size + len) < 0)
160
+ return;
161
+
162
+ memcpy(buf->data + buf->size, data, len);
163
+ buf->size += len;
164
+ }
165
+
166
+ /* bufputs: appends a NUL-terminated string to a buffer */
167
+ void
168
+ bufputs(struct buf *buf, const char *str)
169
+ {
170
+ bufput(buf, str, strlen(str));
171
+ }
172
+
173
+
174
+ /* bufputc: appends a single uint8_t to a buffer */
175
+ void
176
+ bufputc(struct buf *buf, int c)
177
+ {
178
+ assert(buf && buf->unit);
179
+
180
+ if (buf->size + 1 > buf->asize && bufgrow(buf, buf->size + 1) < 0)
181
+ return;
182
+
183
+ buf->data[buf->size] = c;
184
+ buf->size += 1;
185
+ }
186
+
187
+ /* bufrelease: decrease the reference count and free the buffer if needed */
188
+ void
189
+ bufrelease(struct buf *buf)
190
+ {
191
+ if (!buf)
192
+ return;
193
+
194
+ free(buf->data);
195
+ free(buf);
196
+ }
197
+
198
+
199
+ /* bufreset: frees internal data of the buffer */
200
+ void
201
+ bufreset(struct buf *buf)
202
+ {
203
+ if (!buf)
204
+ return;
205
+
206
+ free(buf->data);
207
+ buf->data = NULL;
208
+ buf->size = buf->asize = 0;
209
+ }
210
+
211
+ /* bufslurp: removes a given number of bytes from the head of the array */
212
+ void
213
+ bufslurp(struct buf *buf, size_t len)
214
+ {
215
+ assert(buf && buf->unit);
216
+
217
+ if (len >= buf->size) {
218
+ buf->size = 0;
219
+ return;
220
+ }
221
+
222
+ buf->size -= len;
223
+ memmove(buf->data, buf->data + len, buf->size);
224
+ }
225
+
@@ -0,0 +1,96 @@
1
+ /*
2
+ * Copyright (c) 2008, Natacha Porté
3
+ * Copyright (c) 2011, Vicent Martí
4
+ *
5
+ * Permission to use, copy, modify, and distribute this software for any
6
+ * purpose with or without fee is hereby granted, provided that the above
7
+ * copyright notice and this permission notice appear in all copies.
8
+ *
9
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16
+ */
17
+
18
+ #ifndef BUFFER_H__
19
+ #define BUFFER_H__
20
+
21
+ #include <stddef.h>
22
+ #include <stdarg.h>
23
+ #include <stdint.h>
24
+
25
+ #ifdef __cplusplus
26
+ extern "C" {
27
+ #endif
28
+
29
+ #if defined(_MSC_VER)
30
+ #define __attribute__(x)
31
+ #define inline
32
+ #endif
33
+
34
+ typedef enum {
35
+ BUF_OK = 0,
36
+ BUF_ENOMEM = -1,
37
+ } buferror_t;
38
+
39
+ /* struct buf: character array buffer */
40
+ struct buf {
41
+ uint8_t *data; /* actual character data */
42
+ size_t size; /* size of the string */
43
+ size_t asize; /* allocated size (0 = volatile buffer) */
44
+ size_t unit; /* reallocation unit size (0 = read-only buffer) */
45
+ };
46
+
47
+ /* CONST_BUF: global buffer from a string litteral */
48
+ #define BUF_STATIC(string) \
49
+ { (uint8_t *)string, sizeof string -1, sizeof string, 0, 0 }
50
+
51
+ /* VOLATILE_BUF: macro for creating a volatile buffer on the stack */
52
+ #define BUF_VOLATILE(strname) \
53
+ { (uint8_t *)strname, strlen(strname), 0, 0, 0 }
54
+
55
+ /* BUFPUTSL: optimized bufputs of a string litteral */
56
+ #define BUFPUTSL(output, literal) \
57
+ bufput(output, literal, sizeof literal - 1)
58
+
59
+ /* bufgrow: increasing the allocated size to the given value */
60
+ int bufgrow(struct buf *, size_t);
61
+
62
+ /* bufnew: allocation of a new buffer */
63
+ struct buf *bufnew(size_t) __attribute__ ((malloc));
64
+
65
+ /* bufnullterm: NUL-termination of the string array (making a C-string) */
66
+ const char *bufcstr(struct buf *);
67
+
68
+ /* bufprefix: compare the beginning of a buffer with a string */
69
+ int bufprefix(const struct buf *buf, const char *prefix);
70
+
71
+ /* bufput: appends raw data to a buffer */
72
+ void bufput(struct buf *, const void *, size_t);
73
+
74
+ /* bufputs: appends a NUL-terminated string to a buffer */
75
+ void bufputs(struct buf *, const char *);
76
+
77
+ /* bufputc: appends a single char to a buffer */
78
+ void bufputc(struct buf *, int);
79
+
80
+ /* bufrelease: decrease the reference count and free the buffer if needed */
81
+ void bufrelease(struct buf *);
82
+
83
+ /* bufreset: frees internal data of the buffer */
84
+ void bufreset(struct buf *);
85
+
86
+ /* bufslurp: removes a given number of bytes from the head of the array */
87
+ void bufslurp(struct buf *, size_t);
88
+
89
+ /* bufprintf: formatted printing to a buffer */
90
+ void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));
91
+
92
+ #ifdef __cplusplus
93
+ }
94
+ #endif
95
+
96
+ #endif
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS << " -fvisibility=hidden "
4
+
5
+ dir_config('github/markdown')
6
+ create_makefile('github/markdown')
@@ -0,0 +1,225 @@
1
+ /*
2
+ * Copyright (c) 2012, GitHub, Inc
3
+ *
4
+ * Permission to use, copy, modify, and distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+ #include <ruby.h>
18
+
19
+ #ifdef HAVE_RUBY_ENCODING_H
20
+ # include <ruby/encoding.h>
21
+ # define geefem_str_new(str, len) rb_enc_str_new(str, len, rb_utf8_encoding())
22
+ #else
23
+ # define geefem_str_new(str, len) rb_str_new(str, len)
24
+ #endif
25
+
26
+ #include "markdown.h"
27
+ #include "html.h"
28
+ #include "plaintext.h"
29
+
30
+ #define RUBY_EXPORT __attribute__ ((visibility ("default")))
31
+
32
+ static struct {
33
+ struct sd_markdown *md;
34
+ struct html_renderopt render_opts;
35
+ } g_markdown, g_GFM, g_plaintext;
36
+
37
+ static void
38
+ rndr_blockcode_github(
39
+ struct buf *ob,
40
+ const struct buf *text,
41
+ const struct buf *lang,
42
+ void *opaque)
43
+ {
44
+ if (ob->size)
45
+ bufputc(ob, '\n');
46
+
47
+ if (!text || !text->size) {
48
+ BUFPUTSL(ob, "<pre><code></code></pre>");
49
+ return;
50
+ }
51
+
52
+ if (lang && lang->size) {
53
+ size_t i = 0, lang_size;
54
+ const char *lang_name = NULL;
55
+
56
+ while (i < lang->size && !isspace(lang->data[i]))
57
+ i++;
58
+
59
+ if (lang->data[0] == '.') {
60
+ lang_name = lang->data + 1;
61
+ lang_size = i - 1;
62
+ } else {
63
+ lang_name = lang->data;
64
+ lang_size = i;
65
+ }
66
+
67
+ if (rb_block_given_p()) {
68
+ VALUE hilight;
69
+
70
+ hilight = rb_yield_values(2,
71
+ geefem_str_new(text->data, text->size),
72
+ geefem_str_new(lang_name, lang_size));
73
+
74
+ if (!NIL_P(hilight)) {
75
+ Check_Type(hilight, T_STRING);
76
+ bufput(ob, RSTRING_PTR(hilight), RSTRING_LEN(hilight));
77
+ return;
78
+ }
79
+ }
80
+
81
+ BUFPUTSL(ob, "<pre lang=\"");
82
+ houdini_escape_html0(ob, lang_name, lang_size, 0);
83
+ BUFPUTSL(ob, "\"><code>");
84
+
85
+ } else {
86
+ BUFPUTSL(ob, "<pre><code>");
87
+ }
88
+
89
+ houdini_escape_html0(ob, text->data, text->size, 0);
90
+ BUFPUTSL(ob, "</code></pre>\n");
91
+ }
92
+
93
+ static VALUE rb_ghmd_to_html(VALUE self, VALUE rb_text, VALUE rb_mode)
94
+ {
95
+ struct buf *output_buf;
96
+ struct sd_markdown *md = NULL;
97
+ ID mode;
98
+
99
+ if (NIL_P(rb_text))
100
+ return Qnil;
101
+
102
+ Check_Type(rb_mode, T_SYMBOL);
103
+ mode = SYM2ID(rb_mode);
104
+
105
+ /* check for rendering mode */
106
+ if (mode == rb_intern("markdown")) {
107
+ md = g_markdown.md;
108
+ } else if (mode == rb_intern("gfm")) {
109
+ md = g_GFM.md;
110
+ } else if (mode == rb_intern("plaintext")) {
111
+ md = g_plaintext.md;
112
+ } else {
113
+ rb_raise(rb_eTypeError, "Invalid render mode");
114
+ }
115
+
116
+ Check_Type(rb_text, T_STRING);
117
+
118
+ /* initialize buffers */
119
+ output_buf = bufnew(128);
120
+
121
+ /* render the magic */
122
+ sd_markdown_render(output_buf, RSTRING_PTR(rb_text), RSTRING_LEN(rb_text), md);
123
+
124
+ /* build the Ruby string */
125
+ rb_text = geefem_str_new(output_buf->data, output_buf->size);
126
+
127
+ bufrelease(output_buf);
128
+ return rb_text;
129
+ }
130
+
131
+
132
+ /* Max recursion nesting when parsing Markdown documents */
133
+ static const int GITHUB_MD_NESTING = 32;
134
+
135
+ /* Default flags for all Markdown pipelines:
136
+ *
137
+ * - NO_INTRA_EMPHASIS: disallow emphasis inside of words
138
+ * - LAX_SPACING: Do spacing like in Markdown 1.0.0 (i.e.
139
+ * do not require an empty line between two different
140
+ * blocks in a paragraph)
141
+ * - STRIKETHROUGH: strike out words with `~~`, same semantics
142
+ * as emphasis
143
+ * - TABLES: the tables extension from PHP-Markdown extra
144
+ * - FENCED_CODE: the fenced code blocks extension from
145
+ * PHP-Markdown extra, but working with ``` besides ~~~.
146
+ * - AUTOLINK: Well. That. Link stuff automatically.
147
+ */
148
+ static const int GITHUB_MD_FLAGS =
149
+ MKDEXT_NO_INTRA_EMPHASIS |
150
+ MKDEXT_LAX_SPACING |
151
+ MKDEXT_STRIKETHROUGH |
152
+ MKDEXT_TABLES |
153
+ MKDEXT_FENCED_CODE |
154
+ MKDEXT_AUTOLINK;
155
+
156
+ /* Init the default pipeline */
157
+ static void rb_ghmd__init_md(void)
158
+ {
159
+ struct sd_callbacks callbacks;
160
+
161
+ /* No extra flags to the Markdown renderer */
162
+ sdhtml_renderer(&callbacks, &g_markdown.render_opts, 0);
163
+ callbacks.blockcode = &rndr_blockcode_github;
164
+
165
+ g_markdown.md = sd_markdown_new(
166
+ GITHUB_MD_FLAGS,
167
+ GITHUB_MD_NESTING,
168
+ &callbacks,
169
+ &g_markdown.render_opts
170
+ );
171
+ }
172
+
173
+ /* Init the GFM pipeline */
174
+ static void rb_ghmd__init_gfm(void)
175
+ {
176
+ struct sd_callbacks callbacks;
177
+
178
+ /*
179
+ * The following extensions to the HTML output are enabled:
180
+ *
181
+ * - HARD_WRAP: line breaks are replaced with <br>
182
+ * entities
183
+ */
184
+ sdhtml_renderer(&callbacks, &g_GFM.render_opts, HTML_HARD_WRAP);
185
+ callbacks.blockcode = &rndr_blockcode_github;
186
+
187
+ /* The following extensions to the parser are enabled, on top
188
+ * of the common ones:
189
+ *
190
+ * - SPACE_HEADERS: require a space between the `#` and the
191
+ * name of a header (prevents collisions with the Issues
192
+ * filter)
193
+ */
194
+ g_GFM.md = sd_markdown_new(
195
+ GITHUB_MD_FLAGS | MKDEXT_SPACE_HEADERS,
196
+ GITHUB_MD_NESTING,
197
+ &callbacks,
198
+ &g_GFM.render_opts
199
+ );
200
+ }
201
+
202
+ static void rb_ghmd__init_plaintext(void)
203
+ {
204
+ struct sd_callbacks callbacks;
205
+
206
+ sdtext_renderer(&callbacks);
207
+ g_plaintext.md = sd_markdown_new(
208
+ GITHUB_MD_FLAGS,
209
+ GITHUB_MD_NESTING,
210
+ &callbacks, NULL
211
+ );
212
+ }
213
+
214
+ void RUBY_EXPORT Init_markdown()
215
+ {
216
+ VALUE rb_mGitHub = rb_const_get(rb_cObject, rb_intern("GitHub"));
217
+ VALUE rb_cMarkdown = rb_define_class_under(rb_mGitHub, "Markdown", rb_cObject);
218
+
219
+ rb_define_singleton_method(rb_cMarkdown, "to_html", rb_ghmd_to_html, 2);
220
+
221
+ rb_ghmd__init_md();
222
+ rb_ghmd__init_gfm();
223
+ rb_ghmd__init_plaintext();
224
+ }
225
+