sundown 0.2.3 → 0.3
raw patch · 19 files changed
+675/−604 lines, 19 files
Files
- cbits/autolink.c +10/−10
- cbits/autolink.h +4/−4
- cbits/buffer.c +8/−113
- cbits/buffer.h +16/−28
- cbits/houdini.h +28/−0
- cbits/houdini_href_e.c +108/−0
- cbits/houdini_html_e.c +84/−0
- cbits/html.c +59/−129
- cbits/html.h +8/−12
- cbits/html_smartypants.c +42/−42
- cbits/markdown.c +213/−186
- cbits/markdown.h +24/−24
- cbits/stack.c +1/−1
- src/Text/Sundown/Buffer/Foreign.hsc +13/−13
- src/Text/Sundown/Markdown.hs +2/−2
- src/Text/Sundown/Markdown/Foreign.hsc +19/−8
- src/Text/Sundown/Renderers/Html.hs +12/−7
- src/Text/Sundown/Renderers/Html/Foreign.hsc +18/−17
- sundown.cabal +6/−8
cbits/autolink.c view
@@ -22,7 +22,7 @@ #include <ctype.h> int-sd_autolink_issafe(const char *link, size_t link_len)+sd_autolink_issafe(const uint8_t *link, size_t link_len) { static const size_t valid_uris_count = 4; static const char *valid_uris[] = {@@ -35,7 +35,7 @@ size_t len = strlen(valid_uris[i]); if (link_len > len &&- strncasecmp(link, valid_uris[i], len) == 0 &&+ strncasecmp((char *)link, valid_uris[i], len) == 0 && isalnum(link[len])) return 1; }@@ -44,9 +44,9 @@ } static size_t-autolink_delim(char *data, size_t link_end, size_t offset, size_t size)+autolink_delim(uint8_t *data, size_t link_end, size_t offset, size_t size) {- char cclose, copen = 0;+ uint8_t cclose, copen = 0; size_t i; for (i = 0; i < link_end; ++i)@@ -128,7 +128,7 @@ } static size_t-check_domain(char *data, size_t size)+check_domain(uint8_t *data, size_t size) { size_t i, np = 0; @@ -147,7 +147,7 @@ } size_t-sd_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size)+sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size) { size_t link_end; @@ -177,13 +177,13 @@ } size_t-sd_autolink__email(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size)+sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size) { size_t link_end, rewind; int nb = 0, np = 0; for (rewind = 0; rewind < offset; ++rewind) {- char c = data[-rewind - 1];+ uint8_t c = data[-rewind - 1]; if (isalnum(c)) continue;@@ -198,7 +198,7 @@ return 0; for (link_end = 0; link_end < size; ++link_end) {- char c = data[link_end];+ uint8_t c = data[link_end]; if (isalnum(c)) continue;@@ -226,7 +226,7 @@ } size_t-sd_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size)+sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size) { size_t link_end, rewind = 0, domain_len;
cbits/autolink.h view
@@ -20,16 +20,16 @@ #include "buffer.h" extern int-sd_autolink_issafe(const char *link, size_t link_len);+sd_autolink_issafe(const uint8_t *link, size_t link_len); extern size_t-sd_autolink__www(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size);+sd_autolink__www(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size); extern size_t-sd_autolink__email(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size);+sd_autolink__email(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size); extern size_t-sd_autolink__url(size_t *rewind_p, struct buf *link, char *data, size_t offset, size_t size);+sd_autolink__url(size_t *rewind_p, struct buf *link, uint8_t *data, size_t offset, size_t size); #endif
cbits/buffer.c view
@@ -30,59 +30,7 @@ # define _buf_vsnprintf vsnprintf #endif -/* bufcmp: buffer comparison */ int-bufcmp(const struct buf *a, const struct buf *b)-{- size_t i = 0;- size_t cmplen;-- if (a == b)- return 0;-- if (!a)- return -1;-- if (!b)- return 1;-- cmplen = (a->size < b->size) ? a->size : b->size;-- while (i < cmplen && a->data[i] == b->data[i])- ++i;-- if (i < a->size) {- if (i < b->size) return a->data[i] - b->data[i];- return 1;- } else {- if (i < b->size) return -1;- return 0;- }-}--/* bufcmps: comparison of a string to a buffer */-int-bufcmps(const struct buf *a, const char *b)-{- const size_t len = strlen(b);- size_t cmplen = len;- int r;-- if (!a || !a->size)- return b ? 0 : -1;-- if (len < a->size)- cmplen = a->size;-- r = strncmp(a->data, b, cmplen);-- if (r) return r;- else if (a->size == len) return 0;- else if (a->size < len) return -1;- else return 1;-}--int bufprefix(const struct buf *buf, const char *prefix) { size_t i;@@ -98,42 +46,6 @@ return 0; } --/* bufdup: buffer duplication */-struct buf *-bufdup(const struct buf *src, size_t dupunit)-{- size_t blocks;- struct buf *ret;- if (src == 0)- return 0;-- ret = malloc(sizeof (struct buf));- if (ret == 0)- return 0;-- ret->unit = dupunit;- ret->size = src->size;- ret->ref = 1;- if (!src->size) {- ret->asize = 0;- ret->data = 0;- return ret;- }-- blocks = (src->size + dupunit - 1) / dupunit;- ret->asize = blocks * dupunit;- ret->data = malloc(ret->asize);-- if (ret->data == 0) {- free(ret);- return 0;- }-- memcpy(ret->data, src->data, src->size);- return ret;-}- /* bufgrow: increasing the allocated size to the given value */ int bufgrow(struct buf *buf, size_t neosz)@@ -170,7 +82,6 @@ if (ret) { ret->data = 0; ret->size = ret->asize = 0;- ret->ref = 1; ret->unit = unit; } return ret;@@ -184,11 +95,11 @@ return NULL; if (buf->size < buf->asize && buf->data[buf->size] == 0)- return buf->data;+ return (char *)buf->data; if (buf->size + 1 <= buf->asize || bufgrow(buf, buf->size + 1) == 0) { buf->data[buf->size] = 0;- return buf->data;+ return (char *)buf->data; } return NULL;@@ -229,9 +140,9 @@ } -/* bufputc: appends a single char to a buffer */+/* bufputc: appends a single uint8_t to a buffer */ void-bufputc(struct buf *buf, char c)+bufputc(struct buf *buf, int c) { if (!buf) return;@@ -250,10 +161,8 @@ if (!buf) return; - if (--buf->ref == 0) {- free(buf->data);- free(buf);- }+ free(buf->data);+ free(buf); } @@ -269,20 +178,6 @@ buf->size = buf->asize = 0; } --/* bufset: safely assigns a buffer to another */-void-bufset(struct buf **dest, struct buf *src)-{- if (src) {- if (!src->asize) src = bufdup(src, 1);- else src->ref += 1;- }-- bufrelease(*dest);- *dest = src;-}- /* bufslurp: removes a given number of bytes from the head of the array */ void bufslurp(struct buf *buf, size_t len)@@ -308,7 +203,7 @@ if (buf == 0 || (buf->size >= buf->asize && bufgrow(buf, buf->size + 1)) < 0) return; - n = _buf_vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap);+ n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); if (n < 0) { #ifdef _MSC_VER@@ -322,7 +217,7 @@ if (bufgrow(buf, buf->size + n + 1) < 0) return; - n = _buf_vsnprintf(buf->data + buf->size, buf->asize - buf->size, fmt, ap);+ n = _buf_vsnprintf((char *)buf->data + buf->size, buf->asize - buf->size, fmt, ap); } if (n < 0)
cbits/buffer.h view
@@ -20,6 +20,7 @@ #include <stddef.h> #include <stdarg.h>+#include <stdint.h> #if defined(_MSC_VER) #define __attribute__(x)@@ -33,36 +34,23 @@ /* struct buf: character array buffer */ struct buf {- char *data; /* actual character data */+ uint8_t *data; /* actual character data */ size_t size; /* size of the string */ size_t asize; /* allocated size (0 = volatile buffer) */ size_t unit; /* reallocation unit size (0 = read-only buffer) */- int ref; /* reference count */-}; +}; /* CONST_BUF: global buffer from a string litteral */ #define BUF_STATIC(string) \- { string, sizeof string -1, sizeof string, 0, 0 }+ { (uint8_t *)string, sizeof string -1, sizeof string, 0, 0 } /* VOLATILE_BUF: macro for creating a volatile buffer on the stack */ #define BUF_VOLATILE(strname) \- { strname, strlen(strname), 0, 0, 0 }+ { (uint8_t *)strname, strlen(strname), 0, 0, 0 } /* BUFPUTSL: optimized bufputs of a string litteral */-#define BUFPUTSL(output, litteral) \- bufput(output, litteral, sizeof litteral - 1)--/* bufcmp: case-sensitive buffer comparison */-int bufcmp(const struct buf *, const struct buf *);--/* bufcmps: case-sensitive comparison of a string to a buffer */-int bufcmps(const struct buf *, const char *); --/* bufprefix: compare the beginning of a buffer with a string */-int bufprefix(const struct buf *buf, const char *prefix); --/* bufdup: buffer duplication */-struct buf *bufdup(const struct buf *, size_t) __attribute__ ((malloc));+#define BUFPUTSL(output, literal) \+ bufput(output, literal, sizeof literal - 1) /* bufgrow: increasing the allocated size to the given value */ int bufgrow(struct buf *, size_t);@@ -73,17 +61,17 @@ /* bufnullterm: NUL-termination of the string array (making a C-string) */ const char *bufcstr(struct buf *); -/* bufprintf: formatted printing to a buffer */-void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));+/* bufprefix: compare the beginning of a buffer with a string */+int bufprefix(const struct buf *buf, const char *prefix); /* bufput: appends raw data to a buffer */-void bufput(struct buf *, const void*, size_t);+void bufput(struct buf *, const void *, size_t); /* bufputs: appends a NUL-terminated string to a buffer */-void bufputs(struct buf *, const char*);+void bufputs(struct buf *, const char *); /* bufputc: appends a single char to a buffer */-void bufputc(struct buf *, char);+void bufputc(struct buf *, int); /* bufrelease: decrease the reference count and free the buffer if needed */ void bufrelease(struct buf *);@@ -91,13 +79,13 @@ /* bufreset: frees internal data of the buffer */ void bufreset(struct buf *); -/* bufset: safely assigns a buffer to another */-void bufset(struct buf **, struct buf *);- /* bufslurp: removes a given number of bytes from the head of the array */ void bufslurp(struct buf *, size_t); +/* bufprintf: formatted printing to a buffer */+void bufprintf(struct buf *, const char *, ...) __attribute__ ((format (printf, 2, 3)));+ /* vbufprintf: stdarg variant of formatted printing into a buffer */-void vbufprintf(struct buf *, const char*, va_list);+void vbufprintf(struct buf *, const char * , va_list); #endif
+ cbits/houdini.h view
@@ -0,0 +1,28 @@+#ifndef __HOUDINI_H__+#define __HOUDINI_H__++#include "buffer.h"++#ifdef HOUDINI_USE_LOCALE+# define _isxdigit(c) isxdigit(c)+# define _isdigit(c) isdigit(c)+#else+/*+ * Helper _isdigit methods -- do not trust the current locale+ * */+# define _isxdigit(c) (strchr("0123456789ABCDEFabcdef", (c)) != NULL)+# define _isdigit(c) ((c) >= '0' && (c) <= '9')+#endif++extern void houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure);+extern void houdini_unescape_html(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_escape_uri(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_escape_url(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_unescape_uri(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_unescape_url(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_escape_js(struct buf *ob, const uint8_t *src, size_t size);+extern void houdini_unescape_js(struct buf *ob, const uint8_t *src, size_t size);++#endif
+ cbits/houdini_href_e.c view
@@ -0,0 +1,108 @@+#include <assert.h>+#include <stdio.h>+#include <string.h>++#include "houdini.h"++#define ESCAPE_GROW_FACTOR(x) (((x) * 12) / 10)++/*+ * The following characters will not be escaped:+ *+ * -_.+!*'(),%#@?=;:/,+&$ alphanum+ *+ * Note that this character set is the addition of:+ *+ * - The characters which are safe to be in an URL+ * - The characters which are *not* safe to be in+ * an URL because they are RESERVED characters.+ *+ * We asume (lazily) that any RESERVED char that+ * appears inside an URL is actually meant to+ * have its native function (i.e. as an URL + * component/separator) and hence needs no escaping.+ *+ * There are two exceptions: the chacters & (amp)+ * and ' (single quote) do not appear in the table.+ * They are meant to appear in the URL as components,+ * yet they require special HTML-entity escaping+ * to generate valid HTML markup.+ *+ * All other characters will be escaped to %XX.+ *+ */+static const char HREF_SAFE[] = {+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+};++void+houdini_escape_href(struct buf *ob, const uint8_t *src, size_t size)+{+ static const char hex_chars[] = "0123456789ABCDEF";+ size_t i = 0, org;+ char hex_str[3];++ bufgrow(ob, ESCAPE_GROW_FACTOR(size));+ hex_str[0] = '%';++ while (i < size) {+ org = i;+ while (i < size && HREF_SAFE[src[i]] != 0)+ i++;++ if (i > org)+ bufput(ob, src + org, i - org);++ /* escaping */+ if (i >= size)+ break;++ switch (src[i]) {+ /* amp appears all the time in URLs, but needs+ * HTML-entity escaping to be inside an href */+ case '&': + BUFPUTSL(ob, "&");+ break;++ /* the single quote is a valid URL character+ * according to the standard; it needs HTML+ * entity escaping too */+ case '\'':+ BUFPUTSL(ob, "'");+ break;+ + /* the space can be escaped to %20 or a plus+ * sign. we're going with the generic escape+ * for now. the plus thing is more commonly seen+ * when building GET strings */+#if 0+ case ' ':+ bufputc(ob, '+');+ break;+#endif++ /* every other character goes with a %XX escaping */+ default:+ hex_str[1] = hex_chars[(src[i] >> 4) & 0xF];+ hex_str[2] = hex_chars[src[i] & 0xF];+ bufput(ob, hex_str, 3);+ }++ i++;+ }+}
+ cbits/houdini_html_e.c view
@@ -0,0 +1,84 @@+#include <assert.h>+#include <stdio.h>+#include <string.h>++#include "houdini.h"++#define ESCAPE_GROW_FACTOR(x) (((x) * 12) / 10) /* this is very scientific, yes */++/**+ * According to the OWASP rules:+ *+ * & --> &+ * < --> <+ * > --> >+ * " --> "+ * ' --> ' ' is not recommended+ * / --> / forward slash is included as it helps end an HTML entity+ *+ */+static const char HTML_ESCAPE_TABLE[] = {+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 2, 3, 0, 0, 0, 0, 0, 0, 0, 4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+};++static const char *HTML_ESCAPES[] = {+ "",+ """,+ "&",+ "'",+ "/",+ "<",+ ">"+};++void+houdini_escape_html0(struct buf *ob, const uint8_t *src, size_t size, int secure)+{+ size_t i = 0, org, esc;++ bufgrow(ob, ESCAPE_GROW_FACTOR(size));++ while (i < size) {+ org = i;+ while (i < size && (esc = HTML_ESCAPE_TABLE[src[i]]) == 0)+ i++;++ if (i > org)+ bufput(ob, src + org, i - org);++ /* escaping */+ if (i >= size)+ break;++ /* The forward slash is only escaped in secure mode */+ if (src[i] == '/' && !secure) {+ bufputc(ob, '/');+ } else {+ bufputs(ob, HTML_ESCAPES[esc]);+ }++ i++;+ }+}++void+houdini_escape_html(struct buf *ob, const uint8_t *src, size_t size)+{+ houdini_escape_html0(ob, src, size, 1);+}+
cbits/html.c view
@@ -23,43 +23,12 @@ #include <stdio.h> #include <ctype.h> -#define USE_XHTML(opt) (opt->flags & HTML_USE_XHTML)--static inline void-put_scaped_char(struct buf *ob, char c)-{- switch (c) {- case '<': BUFPUTSL(ob, "<"); break;- case '>': BUFPUTSL(ob, ">"); break;- case '&': BUFPUTSL(ob, "&"); break;- case '"': BUFPUTSL(ob, """); break;- default: bufputc(ob, c); break;- }-}--/* sdhtml_escape • copy the buffer entity-escaping '<', '>', '&' and '"' */-void-sdhtml_escape(struct buf *ob, const char *src, size_t size)-{- size_t i = 0, org;- while (i < size) {- /* copying directly unescaped characters */- org = i;- while (i < size && src[i] != '<' && src[i] != '>'- && src[i] != '&' && src[i] != '"')- i += 1;- if (i > org) bufput(ob, src + org, i - org);-- /* escaping */- if (i >= size) break;+#include "houdini.h" - put_scaped_char(ob, src[i]);- i++;- }-}+#define USE_XHTML(opt) (opt->flags & HTML_USE_XHTML) int-sdhtml_tag(const char *tag_data, size_t tag_size, const char *tagname)+sdhtml_is_tag(const uint8_t *tag_data, size_t tag_size, const char *tagname) { size_t i; int closed = 0;@@ -95,7 +64,7 @@ * GENERIC RENDERER * ********************/ static int-rndr_autolink(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque)+rndr_autolink(struct buf *ob, const struct buf *link, enum mkd_autolink type, void *opaque) { struct html_renderopt *options = opaque; @@ -110,7 +79,7 @@ BUFPUTSL(ob, "<a href=\""); if (type == MKDA_EMAIL) BUFPUTSL(ob, "mailto:");- sdhtml_escape(ob, link->data, link->size);+ houdini_escape_href(ob, link->data, link->size); if (options->link_attributes) { bufputc(ob, '\"');@@ -126,9 +95,9 @@ * want to print the `mailto:` prefix */ if (bufprefix(link, "mailto:") == 0) {- sdhtml_escape(ob, link->data + 7, link->size - 7);+ houdini_escape_html(ob, link->data + 7, link->size - 7); } else {- sdhtml_escape(ob, link->data, link->size);+ houdini_escape_html(ob, link->data, link->size); } BUFPUTSL(ob, "</a>");@@ -137,7 +106,7 @@ } static void-rndr_blockcode(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)+rndr_blockcode(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque) { if (ob->size) bufputc(ob, '\n'); @@ -158,7 +127,7 @@ org++; if (cls) bufputc(ob, ' ');- sdhtml_escape(ob, lang->data + org, i - org);+ houdini_escape_html(ob, lang->data + org, i - org); } } @@ -167,58 +136,13 @@ BUFPUTSL(ob, "<pre><code>"); if (text)- sdhtml_escape(ob, text->data, text->size);-- BUFPUTSL(ob, "</code></pre>\n");-}--/*- * GitHub style code block:- *- * <pre lang="LANG"><code>- * ...- * </pre></code>- *- * Unlike other parsers, we store the language identifier in the <pre>,- * and don't let the user generate custom classes.- *- * The language identifier in the <pre> block gets postprocessed and all- * the code inside gets syntax highlighted with Pygments. This is much safer- * than letting the user specify a CSS class for highlighting.- *- * Note that we only generate HTML for the first specifier.- * E.g.- * ~~~~ {.python .numbered} => <pre lang="python"><code>- */-static void-rndr_blockcode_github(struct buf *ob, struct buf *text, struct buf *lang, void *opaque)-{- if (ob->size) bufputc(ob, '\n');-- if (lang && lang->size) {- size_t i = 0;- BUFPUTSL(ob, "<pre lang=\"");-- while (i < lang->size && !isspace(lang->data[i]))- i++;-- if (lang->data[0] == '.')- sdhtml_escape(ob, lang->data + 1, i - 1);- else- sdhtml_escape(ob, lang->data, i);-- BUFPUTSL(ob, "\"><code>");- } else- BUFPUTSL(ob, "<pre><code>");-- if (text)- sdhtml_escape(ob, text->data, text->size);+ houdini_escape_html(ob, text->data, text->size); BUFPUTSL(ob, "</code></pre>\n"); } static void-rndr_blockquote(struct buf *ob, struct buf *text, void *opaque)+rndr_blockquote(struct buf *ob, const struct buf *text, void *opaque) { if (ob->size) bufputc(ob, '\n'); BUFPUTSL(ob, "<blockquote>\n");@@ -227,16 +151,16 @@ } static int-rndr_codespan(struct buf *ob, struct buf *text, void *opaque)+rndr_codespan(struct buf *ob, const struct buf *text, void *opaque) { BUFPUTSL(ob, "<code>");- if (text) sdhtml_escape(ob, text->data, text->size);+ if (text) houdini_escape_html(ob, text->data, text->size); BUFPUTSL(ob, "</code>"); return 1; } static int-rndr_strikethrough(struct buf *ob, struct buf *text, void *opaque)+rndr_strikethrough(struct buf *ob, const struct buf *text, void *opaque) { if (!text || !text->size) return 0;@@ -248,7 +172,7 @@ } static int-rndr_double_emphasis(struct buf *ob, struct buf *text, void *opaque)+rndr_double_emphasis(struct buf *ob, const struct buf *text, void *opaque) { if (!text || !text->size) return 0;@@ -261,7 +185,7 @@ } static int-rndr_emphasis(struct buf *ob, struct buf *text, void *opaque)+rndr_emphasis(struct buf *ob, const struct buf *text, void *opaque) { if (!text || !text->size) return 0; BUFPUTSL(ob, "<em>");@@ -273,16 +197,16 @@ static int rndr_linebreak(struct buf *ob, void *opaque) {- struct html_renderopt *options = opaque; + struct html_renderopt *options = opaque; bufputs(ob, USE_XHTML(options) ? "<br/>\n" : "<br>\n"); return 1; } static void-rndr_header(struct buf *ob, struct buf *text, int level, void *opaque)+rndr_header(struct buf *ob, const struct buf *text, int level, void *opaque) { struct html_renderopt *options = opaque;- + if (ob->size) bufputc(ob, '\n'); @@ -296,21 +220,21 @@ } static int-rndr_link(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque)+rndr_link(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque) { struct html_renderopt *options = opaque;- + if (link != NULL && (options->flags & HTML_SAFELINK) != 0 && !sd_autolink_issafe(link->data, link->size)) return 0; BUFPUTSL(ob, "<a href=\""); if (link && link->size)- sdhtml_escape(ob, link->data, link->size);+ houdini_escape_href(ob, link->data, link->size); if (title && title->size) { BUFPUTSL(ob, "\" title=\"");- sdhtml_escape(ob, title->data, title->size);+ houdini_escape_html(ob, title->data, title->size); } if (options->link_attributes) {@@ -327,7 +251,7 @@ } static void-rndr_list(struct buf *ob, struct buf *text, int flags, void *opaque)+rndr_list(struct buf *ob, const struct buf *text, int flags, void *opaque) { if (ob->size) bufputc(ob, '\n'); bufput(ob, flags & MKD_LIST_ORDERED ? "<ol>\n" : "<ul>\n", 5);@@ -336,18 +260,21 @@ } static void-rndr_listitem(struct buf *ob, struct buf *text, int flags, void *opaque)+rndr_listitem(struct buf *ob, const struct buf *text, int flags, void *opaque) { BUFPUTSL(ob, "<li>"); if (text) {- while (text->size && text->data[text->size - 1] == '\n')- text->size -= 1;- bufput(ob, text->data, text->size); }+ size_t size = text->size;+ while (size && text->data[size - 1] == '\n')+ size--;++ bufput(ob, text->data, size);+ } BUFPUTSL(ob, "</li>\n"); } static void-rndr_paragraph(struct buf *ob, struct buf *text, void *opaque)+rndr_paragraph(struct buf *ob, const struct buf *text, void *opaque) { struct html_renderopt *options = opaque; size_t i = 0;@@ -379,7 +306,7 @@ */ if (i >= text->size - 1) break;- + rndr_linebreak(ob, opaque); i++; }@@ -390,7 +317,7 @@ } static void-rndr_raw_block(struct buf *ob, struct buf *text, void *opaque)+rndr_raw_block(struct buf *ob, const struct buf *text, void *opaque) { size_t org, sz; if (!text) return;@@ -405,7 +332,7 @@ } static int-rndr_triple_emphasis(struct buf *ob, struct buf *text, void *opaque)+rndr_triple_emphasis(struct buf *ob, const struct buf *text, void *opaque) { if (!text || !text->size) return 0; BUFPUTSL(ob, "<strong><em>");@@ -417,44 +344,50 @@ static void rndr_hrule(struct buf *ob, void *opaque) {- struct html_renderopt *options = opaque; + struct html_renderopt *options = opaque; if (ob->size) bufputc(ob, '\n'); bufputs(ob, USE_XHTML(options) ? "<hr/>\n" : "<hr>\n"); } static int-rndr_image(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, void *opaque)+rndr_image(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque) {- struct html_renderopt *options = opaque; + struct html_renderopt *options = opaque; if (!link || !link->size) return 0;+ BUFPUTSL(ob, "<img src=\"");- sdhtml_escape(ob, link->data, link->size);+ houdini_escape_href(ob, link->data, link->size); BUFPUTSL(ob, "\" alt=\"");+ if (alt && alt->size)- sdhtml_escape(ob, alt->data, alt->size);+ houdini_escape_html(ob, alt->data, alt->size);+ if (title && title->size) { BUFPUTSL(ob, "\" title=\"");- sdhtml_escape(ob, title->data, title->size); }+ houdini_escape_html(ob, title->data, title->size); } bufputs(ob, USE_XHTML(options) ? "\"/>" : "\">"); return 1; } static int-rndr_raw_html(struct buf *ob, struct buf *text, void *opaque)+rndr_raw_html(struct buf *ob, const struct buf *text, void *opaque) {- struct html_renderopt *options = opaque; + struct html_renderopt *options = opaque; if ((options->flags & HTML_SKIP_HTML) != 0) return 1; - if ((options->flags & HTML_SKIP_STYLE) != 0 && sdhtml_tag(text->data, text->size, "style"))+ if ((options->flags & HTML_SKIP_STYLE) != 0 &&+ sdhtml_is_tag(text->data, text->size, "style")) return 1; - if ((options->flags & HTML_SKIP_LINKS) != 0 && sdhtml_tag(text->data, text->size, "a"))+ if ((options->flags & HTML_SKIP_LINKS) != 0 &&+ sdhtml_is_tag(text->data, text->size, "a")) return 1; - if ((options->flags & HTML_SKIP_IMAGES) != 0 && sdhtml_tag(text->data, text->size, "img"))+ if ((options->flags & HTML_SKIP_IMAGES) != 0 &&+ sdhtml_is_tag(text->data, text->size, "img")) return 1; bufput(ob, text->data, text->size);@@ -462,7 +395,7 @@ } static void-rndr_table(struct buf *ob, struct buf *header, struct buf *body, void *opaque)+rndr_table(struct buf *ob, const struct buf *header, const struct buf *body, void *opaque) { if (ob->size) bufputc(ob, '\n'); BUFPUTSL(ob, "<table><thead>\n");@@ -475,7 +408,7 @@ } static void-rndr_tablerow(struct buf *ob, struct buf *text, void *opaque)+rndr_tablerow(struct buf *ob, const struct buf *text, void *opaque) { BUFPUTSL(ob, "<tr>\n"); if (text)@@ -484,7 +417,7 @@ } static void-rndr_tablecell(struct buf *ob, struct buf *text, int flags, void *opaque)+rndr_tablecell(struct buf *ob, const struct buf *text, int flags, void *opaque) { if (flags & MKD_TABLE_HEADER) { BUFPUTSL(ob, "<th");@@ -520,7 +453,7 @@ } static int-rndr_superscript(struct buf *ob, struct buf *text, void *opaque)+rndr_superscript(struct buf *ob, const struct buf *text, void *opaque) { if (!text || !text->size) return 0; BUFPUTSL(ob, "<sup>");@@ -530,14 +463,14 @@ } static void-rndr_normal_text(struct buf *ob, struct buf *text, void *opaque)+rndr_normal_text(struct buf *ob, const struct buf *text, void *opaque) { if (text)- sdhtml_escape(ob, text->data, text->size);+ houdini_escape_html(ob, text->data, text->size); } static void-toc_header(struct buf *ob, struct buf *text, int level, void *opaque)+toc_header(struct buf *ob, const struct buf *text, int level, void *opaque) { struct html_renderopt *options = opaque; @@ -667,7 +600,4 @@ if (render_flags & HTML_SKIP_HTML) callbacks->blockhtml = NULL;-- if (render_flags & HTML_GITHUB_BLOCKCODE)- callbacks->blockcode = rndr_blockcode_github; }
cbits/html.h view
@@ -30,7 +30,7 @@ unsigned int flags; /* extra callbacks */- void (*link_attributes)(struct buf *ob, struct buf *url, void *self);+ void (*link_attributes)(struct buf *ob, const struct buf *url, void *self); }; typedef enum {@@ -38,12 +38,11 @@ HTML_SKIP_STYLE = (1 << 1), HTML_SKIP_IMAGES = (1 << 2), HTML_SKIP_LINKS = (1 << 3),- HTML_EXPAND_TABS = (1 << 5),- HTML_SAFELINK = (1 << 7),- HTML_TOC = (1 << 8),- HTML_HARD_WRAP = (1 << 9),- HTML_GITHUB_BLOCKCODE = (1 << 10),- HTML_USE_XHTML = (1 << 11),+ HTML_EXPAND_TABS = (1 << 4),+ HTML_SAFELINK = (1 << 5),+ HTML_TOC = (1 << 6),+ HTML_HARD_WRAP = (1 << 7),+ HTML_USE_XHTML = (1 << 8), } html_render_mode; typedef enum {@@ -52,11 +51,8 @@ HTML_TAG_CLOSE, } html_tag; -void-sdhtml_escape(struct buf *ob, const char *src, size_t size);- int-sdhtml_tag(const char *tag_data, size_t tag_size, const char *tagname);+sdhtml_is_tag(const uint8_t *tag_data, size_t tag_size, const char *tagname); extern void sdhtml_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options_ptr, unsigned int render_flags);@@ -65,7 +61,7 @@ sdhtml_toc_renderer(struct sd_callbacks *callbacks, struct html_renderopt *options_ptr); extern void-sdhtml_smartypants(struct buf *ob, struct buf *text);+sdhtml_smartypants(struct buf *ob, const uint8_t *text, size_t size); #endif
cbits/html_smartypants.c view
@@ -27,19 +27,19 @@ int in_dquote; }; -static size_t smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__amp(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__period(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__dash(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__squote(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__backtick(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);-static size_t smartypants_cb__escape(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size);+static size_t smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__amp(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__period(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__dash(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__backtick(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size);+static size_t smartypants_cb__escape(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size); static size_t (*smartypants_cb_ptrs[])- (struct buf *, struct smartypants_data *, char, const char *, size_t) = + (struct buf *, struct smartypants_data *, uint8_t, const uint8_t *, size_t) = { NULL, /* 0 */ smartypants_cb__dash, /* 1 */@@ -54,7 +54,7 @@ smartypants_cb__escape, /* 10 */ }; -static const char smartypants_cb_chars[] = {+static const uint8_t smartypants_cb_chars[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 5, 3, 2, 0, 0, 0, 0, 1, 6, 0,@@ -74,13 +74,13 @@ }; static inline int-word_boundary(char c)+word_boundary(uint8_t c) { return c == 0 || isspace(c) || ispunct(c); } static int-smartypants_quotes(struct buf *ob, char previous_char, char next_char, char quote, int *is_open)+smartypants_quotes(struct buf *ob, uint8_t previous_char, uint8_t next_char, uint8_t quote, int *is_open) { char ent[8]; @@ -97,10 +97,10 @@ } static size_t-smartypants_cb__squote(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__squote(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (size >= 2) {- char t1 = tolower(text[1]);+ uint8_t t1 = tolower(text[1]); if (t1 == '\'') { if (smartypants_quotes(ob, previous_char, size >= 3 ? text[2] : 0, 'd', &smrt->in_dquote))@@ -114,7 +114,7 @@ } if (size >= 3) {- char t2 = tolower(text[2]);+ uint8_t t2 = tolower(text[2]); if (((t1 == 'r' && t2 == 'e') || (t1 == 'l' && t2 == 'l') ||@@ -134,11 +134,11 @@ } static size_t-smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__parens(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (size >= 3) {- char t1 = tolower(text[1]);- char t2 = tolower(text[2]);+ uint8_t t1 = tolower(text[1]);+ uint8_t t2 = tolower(text[2]); if (t1 == 'c' && t2 == ')') { BUFPUTSL(ob, "©");@@ -155,13 +155,13 @@ return 3; } }- + bufputc(ob, text[0]); return 0; } static size_t-smartypants_cb__dash(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__dash(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (size >= 3 && text[1] == '-' && text[2] == '-') { BUFPUTSL(ob, "—");@@ -178,7 +178,7 @@ } static size_t-smartypants_cb__amp(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__amp(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (size >= 6 && memcmp(text, """, 6) == 0) { if (smartypants_quotes(ob, previous_char, size >= 7 ? text[6] : 0, 'd', &smrt->in_dquote))@@ -193,7 +193,7 @@ } static size_t-smartypants_cb__period(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__period(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (size >= 3 && text[1] == '.' && text[2] == '.') { BUFPUTSL(ob, "…");@@ -210,7 +210,7 @@ } static size_t-smartypants_cb__backtick(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__backtick(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (size >= 2 && text[1] == '`') { if (smartypants_quotes(ob, previous_char, size >= 3 ? text[2] : 0, 'd', &smrt->in_dquote))@@ -221,7 +221,7 @@ } static size_t-smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__number(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (word_boundary(previous_char) && size >= 3) { if (text[0] == '1' && text[1] == '/' && text[2] == '2') {@@ -253,7 +253,7 @@ } static size_t-smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__dquote(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (!smartypants_quotes(ob, previous_char, size > 0 ? text[1] : 0, 'd', &smrt->in_dquote)) BUFPUTSL(ob, """);@@ -262,7 +262,7 @@ } static size_t-smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__ltag(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { static const char *skip_tags[] = {"pre", "code", "kbd", "script"}; static const size_t skip_tags_count = 4;@@ -273,7 +273,7 @@ i++; for (tag = 0; tag < skip_tags_count; ++tag) {- if (sdhtml_tag(text, size, skip_tags[tag]) == HTML_TAG_OPEN)+ if (sdhtml_is_tag(text, size, skip_tags[tag]) == HTML_TAG_OPEN) break; } @@ -285,7 +285,7 @@ if (i == size) break; - if (sdhtml_tag(text + i, size - i, skip_tags[tag]) == HTML_TAG_CLOSE)+ if (sdhtml_is_tag(text + i, size - i, skip_tags[tag]) == HTML_TAG_CLOSE) break; i++;@@ -300,7 +300,7 @@ } static size_t-smartypants_cb__escape(struct buf *ob, struct smartypants_data *smrt, char previous_char, const char *text, size_t size)+smartypants_cb__escape(struct buf *ob, struct smartypants_data *smrt, uint8_t previous_char, const uint8_t *text, size_t size) { if (size < 2) return 0;@@ -323,9 +323,9 @@ #if 0 static struct {- char c0;- const char *pattern;- const char *entity;+ uint8_t c0;+ const uint8_t *pattern;+ const uint8_t *entity; int skip; } smartypants_subs[] = { { '\'', "'s>", "’", 0 },@@ -352,7 +352,7 @@ #endif void-sdhtml_smartypants(struct buf *ob, struct buf *text)+sdhtml_smartypants(struct buf *ob, const uint8_t *text, size_t size) { size_t i; struct smartypants_data smrt = {0, 0};@@ -360,22 +360,22 @@ if (!text) return; - bufgrow(ob, text->size);+ bufgrow(ob, size); - for (i = 0; i < text->size; ++i) {+ for (i = 0; i < size; ++i) { size_t org;- char action = 0;+ uint8_t action = 0; org = i;- while (i < text->size && (action = smartypants_cb_chars[(unsigned char)text->data[i]]) == 0)+ while (i < size && (action = smartypants_cb_chars[text[i]]) == 0) i++; if (i > org)- bufput(ob, text->data + org, i - org);+ bufput(ob, text + org, i - org); - if (i < text->size) {+ if (i < size) { i += smartypants_cb_ptrs[(int)action]- (ob, &smrt, i ? text->data[i - 1] : 0, text->data + i, text->size - i);+ (ob, &smrt, i ? text[i - 1] : 0, text + i, size - i); } } }
cbits/markdown.c view
@@ -45,8 +45,8 @@ struct link_ref { unsigned int id; - struct buf link;- struct buf title;+ struct buf *link;+ struct buf *title; struct link_ref *next; };@@ -57,19 +57,19 @@ /* offset is the number of valid chars before data */ struct sd_markdown; typedef size_t-(*char_trigger)(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);+(*char_trigger)(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size); -static size_t char_emphasis(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_linebreak(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_codespan(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_escape(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_entity(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_langle_tag(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_autolink_url(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_autolink_email(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_autolink_www(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_link(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);-static size_t char_superscript(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size);+static size_t char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_linebreak(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_entity(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_langle_tag(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_autolink_email(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size);+static size_t char_superscript(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size); enum markdown_char_t { MD_CHAR_NONE = 0,@@ -107,7 +107,7 @@ void *opaque; struct link_ref *refs[REF_TABLE_SIZE];- char active_char[256];+ uint8_t active_char[256]; struct stack work_bufs[2]; unsigned int ext_flags; size_t max_nesting;@@ -163,7 +163,7 @@ } static unsigned int-hash_link_ref(char *link_ref, size_t length)+hash_link_ref(const uint8_t *link_ref, size_t length) { size_t i; unsigned int hash = 0;@@ -174,31 +174,25 @@ return hash; } -static void add_link_ref(+static struct link_ref *+add_link_ref( struct link_ref **references,- char *name, size_t name_size,- char *link, size_t link_size,- char *title, size_t title_size)+ const uint8_t *name, size_t name_size) { struct link_ref *ref = calloc(1, sizeof(struct link_ref)); if (!ref)- return;+ return NULL; ref->id = hash_link_ref(name, name_size); ref->next = references[ref->id % REF_TABLE_SIZE]; - ref->link.data = link;- ref->link.size = link_size;-- ref->title.data = title;- ref->title.size = title_size;- references[ref->id % REF_TABLE_SIZE] = ref;+ return ref; } static struct link_ref *-find_link_ref(struct link_ref **references, char *name, size_t length)+find_link_ref(struct link_ref **references, uint8_t *name, size_t length) { unsigned int hash = hash_link_ref(name, length); struct link_ref *ref = NULL;@@ -225,11 +219,32 @@ struct link_ref *next; while (r) {- next = r->next; free(r); r = next;+ next = r->next;+ bufrelease(r->link);+ bufrelease(r->title);+ free(r);+ r = next; } } } +/*+ * Check whether a char is a Markdown space.++ * Right now we only consider spaces the actual+ * space and a newline: tabs and carriage returns+ * are filtered out during the preprocessing phase.+ *+ * If we wanted to actually be UTF-8 compliant, we+ * should instead extract an Unicode codepoint from+ * this character and check for space properties.+ */+static inline int+_isspace(int c)+{+ return c == ' ' || c == '\n';+}+ /**************************** * INLINE PARSING FUNCTIONS * ****************************/@@ -237,7 +252,7 @@ /* is_mail_autolink • looks for the address part of a mail autolink and '>' */ /* this is less strict than the original markdown e-mail address matching */ static size_t-is_mail_autolink(char *data, size_t size)+is_mail_autolink(uint8_t *data, size_t size) { size_t i = 0, nb = 0; @@ -268,7 +283,7 @@ /* tag_length • returns the length of the given tag, or 0 is it's not valid */ static size_t-tag_length(char *data, size_t size, enum mkd_autolink *autolink)+tag_length(uint8_t *data, size_t size, enum mkd_autolink *autolink) { size_t i, j; @@ -311,7 +326,8 @@ while (i < size) { if (data[i] == '\\') i += 2; else if (data[i] == '>' || data[i] == '\'' ||- data[i] == '"' || isspace(data[i])) break;+ data[i] == '"' || data[i] == ' ' || data[i] == '\n')+ break; else i++; } @@ -329,19 +345,19 @@ /* parse_inline • parses inline markdown elements */ static void-parse_inline(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_inline(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t i = 0, end = 0;- char action = 0;- struct buf work = { 0, 0, 0, 0, 0 };+ uint8_t action = 0;+ struct buf work = { 0, 0, 0, 0 }; if (rndr->work_bufs[BUFFER_SPAN].size +- rndr->work_bufs[BUFFER_BLOCK].size > (int)rndr->max_nesting)+ rndr->work_bufs[BUFFER_BLOCK].size > rndr->max_nesting) return; while (i < size) { /* copying inactive chars into the output */- while (end < size && (action = rndr->active_char[(unsigned char)data[end]]) == 0) {+ while (end < size && (action = rndr->active_char[data[end]]) == 0) { end++; } @@ -367,9 +383,9 @@ } } -/* find_emph_char • looks for the next emph char, skipping other constructs */+/* find_emph_char • looks for the next emph uint8_t, skipping other constructs */ static size_t-find_emph_char(char *data, size_t size, char c)+find_emph_char(uint8_t *data, size_t size, uint8_t c) { size_t i = 1; @@ -414,7 +430,7 @@ /* skipping a link */ else if (data[i] == '[') { size_t tmp_i = 0;- char cc;+ uint8_t cc; i++; while (i < size && data[i] != ']') {@@ -423,7 +439,7 @@ } i++;- while (i < size && (data[i] == ' ' || data[i] == '\t' || data[i] == '\n'))+ while (i < size && (data[i] == ' ' || data[i] == '\n')) i++; if (i >= size)@@ -462,7 +478,7 @@ /* parse_emph1 • parsing single emphase */ /* closed by a symbol not preceded by whitespace and not followed by symbol */ static size_t-parse_emph1(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, char c)+parse_emph1(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, uint8_t c) { size_t i = 0, len; struct buf *work = 0;@@ -479,10 +495,10 @@ i += len; if (i >= size) return 0; - if (data[i] == c && !isspace(data[i - 1])) {+ if (data[i] == c && !_isspace(data[i - 1])) { if (rndr->ext_flags & MKDEXT_NO_INTRA_EMPHASIS) {- if (!(i + 1 == size || isspace(data[i + 1]) || ispunct(data[i + 1])))+ if (!(i + 1 == size || _isspace(data[i + 1]) || ispunct(data[i + 1]))) continue; } @@ -499,9 +515,9 @@ /* parse_emph2 • parsing single emphase */ static size_t-parse_emph2(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, char c)+parse_emph2(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, uint8_t c) {- int (*render_method)(struct buf *ob, struct buf *text, void *opaque);+ int (*render_method)(struct buf *ob, const struct buf *text, void *opaque); size_t i = 0, len; struct buf *work = 0; int r;@@ -516,7 +532,7 @@ if (!len) return 0; i += len; - if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !isspace(data[i - 1])) {+ if (i + 1 < size && data[i] == c && data[i + 1] == c && i && !_isspace(data[i - 1])) { work = rndr_newbuf(rndr, BUFFER_SPAN); parse_inline(work, rndr, data, i); r = render_method(ob, work, rndr->opaque);@@ -531,7 +547,7 @@ /* parse_emph3 • parsing single emphase */ /* finds the first closing tag, and delegates to the other emph */ static size_t-parse_emph3(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, char c)+parse_emph3(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, uint8_t c) { size_t i = 0, len; int r;@@ -542,7 +558,7 @@ i += len; /* skip whitespace preceded symbols */- if (data[i] != c || isspace(data[i - 1]))+ if (data[i] != c || _isspace(data[i - 1])) continue; if (i + 2 < size && data[i + 1] == c && data[i + 2] == c && rndr->cb.triple_emphasis) {@@ -572,29 +588,29 @@ /* char_emphasis • single and double emphasis parsing */ static size_t-char_emphasis(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_emphasis(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) {- char c = data[0];+ uint8_t c = data[0]; size_t ret; if (size > 2 && data[1] != c) { /* whitespace cannot follow an opening emphasis; * strikethrough only takes two characters '~~' */- if (c == '~' || isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0)+ if (c == '~' || _isspace(data[1]) || (ret = parse_emph1(ob, rndr, data + 1, size - 1, c)) == 0) return 0; return ret + 1; } if (size > 3 && data[1] == c && data[2] != c) {- if (isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c)) == 0)+ if (_isspace(data[2]) || (ret = parse_emph2(ob, rndr, data + 2, size - 2, c)) == 0) return 0; return ret + 2; } if (size > 4 && data[1] == c && data[2] == c && data[3] != c) {- if (c == '~' || isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0)+ if (c == '~' || _isspace(data[3]) || (ret = parse_emph3(ob, rndr, data + 3, size - 3, c)) == 0) return 0; return ret + 3;@@ -606,7 +622,7 @@ /* char_linebreak • '\n' preceded by two spaces (assuming linebreak != 0) */ static size_t-char_linebreak(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_linebreak(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { if (offset < 2 || data[-1] != ' ' || data[-2] != ' ') return 0;@@ -621,7 +637,7 @@ /* char_codespan • '`' parsing a code span (assuming codespan != 0) */ static size_t-char_codespan(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_codespan(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { size_t end, nb = 0, i, f_begin, f_end; @@ -641,16 +657,16 @@ /* trimming outside whitespaces */ f_begin = nb;- while (f_begin < end && (data[f_begin] == ' ' || data[f_begin] == '\t'))+ while (f_begin < end && data[f_begin] == ' ') f_begin++; f_end = end - nb;- while (f_end > nb && (data[f_end-1] == ' ' || data[f_end-1] == '\t'))+ while (f_end > nb && data[f_end-1] == ' ') f_end--; /* real code span */ if (f_begin < f_end) {- struct buf work = { data + f_begin, f_end - f_begin, 0, 0, 0 };+ struct buf work = { data + f_begin, f_end - f_begin, 0, 0 }; if (!rndr->cb.codespan(ob, &work, rndr->opaque)) end = 0; } else {@@ -664,10 +680,10 @@ /* char_escape • '\\' backslash escape */ static size_t-char_escape(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_escape(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { static const char *escape_chars = "\\`*_{}[]()#+-.!:|&<>";- struct buf work = { 0, 0, 0, 0, 0 };+ struct buf work = { 0, 0, 0, 0 }; if (size > 1) { if (strchr(escape_chars, data[1]) == NULL)@@ -687,10 +703,10 @@ /* char_entity • '&' escaped when it doesn't belong to an entity */ /* valid entities are assumed to be anything matching &#?[A-Za-z0-9]+; */ static size_t-char_entity(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_entity(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { size_t end = 1;- struct buf work;+ struct buf work = { 0, 0, 0, 0 }; if (end < size && data[end] == '#') end++;@@ -715,11 +731,11 @@ /* char_langle_tag • '<' when tags or autolinks are allowed */ static size_t-char_langle_tag(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_langle_tag(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { enum mkd_autolink altype = MKDA_NOT_AUTOLINK; size_t end = tag_length(data, size, &altype);- struct buf work = { data, end, 0, 0, 0 };+ struct buf work = { data, end, 0, 0 }; int ret = 0; if (end > 2) {@@ -740,7 +756,7 @@ } static size_t-char_autolink_www(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_autolink_www(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { struct buf *link, *link_url; size_t link_len, rewind;@@ -765,7 +781,7 @@ } static size_t-char_autolink_email(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_autolink_email(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { struct buf *link; size_t link_len, rewind;@@ -785,7 +801,7 @@ } static size_t-char_autolink_url(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_autolink_url(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { struct buf *link; size_t link_len, rewind;@@ -806,7 +822,7 @@ /* char_link • '[': parsing a link or an image */ static size_t-char_link(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_link(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { int is_img = (offset && data[-1] == '!'), level; size_t i = 1, txt_e, link_b = 0, link_e = 0, title_b = 0, title_e = 0;@@ -847,7 +863,7 @@ /* skip any amount of whitespace or newline */ /* (this is much more laxist than original markdown syntax) */- while (i < size && isspace(data[i]))+ while (i < size && _isspace(data[i])) i++; /* inline style link */@@ -855,7 +871,7 @@ /* skipping initial whitespace */ i++; - while (i < size && isspace(data[i]))+ while (i < size && _isspace(data[i])) i++; link_b = i;@@ -885,7 +901,7 @@ /* skipping whitespaces after title */ title_e = i - 1;- while (title_e > title_b && isspace(data[title_e]))+ while (title_e > title_b && _isspace(data[title_e])) title_e--; /* checking for closing quote presence */@@ -896,7 +912,7 @@ } /* remove whitespace at the end of the link */- while (link_e > link_b && isspace(data[link_e - 1]))+ while (link_e > link_b && _isspace(data[link_e - 1])) link_e--; /* remove optional angle brackets around the link */@@ -919,7 +935,7 @@ /* reference style link */ else if (i < size && data[i] == '[') {- struct buf id = { 0, 0, 0, 0, 0 };+ struct buf id = { 0, 0, 0, 0 }; struct link_ref *lr; /* looking for the id */@@ -958,15 +974,14 @@ goto cleanup; /* keeping link and title from link_ref */- link = &lr->link;- if (lr->title.size)- title = &lr->title;+ link = lr->link;+ title = lr->title; i++; } /* shortcut reference style link */ else {- struct buf id = { 0, 0, 0, 0, 0 };+ struct buf id = { 0, 0, 0, 0 }; struct link_ref *lr; /* crafting the id */@@ -994,9 +1009,8 @@ goto cleanup; /* keeping link and title from link_ref */- link = &lr->link;- if (lr->title.size)- title = &lr->title;+ link = lr->link;+ title = lr->title; /* rewinding the whitespace */ i = txt_e + 1;@@ -1031,7 +1045,7 @@ } static size_t-char_superscript(struct buf *ob, struct sd_markdown *rndr, char *data, size_t offset, size_t size)+char_superscript(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t offset, size_t size) { size_t sup_start, sup_len; struct buf *sup;@@ -1053,7 +1067,7 @@ } else { sup_start = sup_len = 1; - while (sup_len < size && !isspace(data[sup_len]))+ while (sup_len < size && !_isspace(data[sup_len])) sup_len++; } @@ -1074,20 +1088,23 @@ /* is_empty • returns the line length when it is empty, 0 otherwise */ static size_t-is_empty(char *data, size_t size)+is_empty(uint8_t *data, size_t size) { size_t i;+ for (i = 0; i < size && data[i] != '\n'; i++)- if (data[i] != ' ' && data[i] != '\t') return 0;+ if (data[i] != ' ')+ return 0;+ return i + 1; } /* is_hrule • returns whether a line is a horizontal rule */ static int-is_hrule(char *data, size_t size)+is_hrule(uint8_t *data, size_t size) { size_t i = 0, n = 0;- char c;+ uint8_t c; /* skipping initial spaces */ if (size < 3) return 0;@@ -1095,7 +1112,7 @@ if (data[1] == ' ') { i++; if (data[2] == ' ') { i++; } } } - /* looking at the hrule char */+ /* looking at the hrule uint8_t */ if (i + 2 >= size || (data[i] != '*' && data[i] != '-' && data[i] != '_')) return 0;@@ -1104,19 +1121,21 @@ /* the whole line must be the char or whitespace */ while (i < size && data[i] != '\n') { if (data[i] == c) n++;- else if (data[i] != ' ' && data[i] != '\t')+ else if (data[i] != ' ') return 0;- i++; } + i++;+ }+ return n >= 3; } /* check if a line is a code fence; return its size if it is */ static size_t-is_codefence(char *data, size_t size, struct buf *syntax)+is_codefence(uint8_t *data, size_t size, struct buf *syntax) { size_t i = 0, n = 0;- char c;+ uint8_t c; /* skipping initial spaces */ if (size < 3) return 0;@@ -1124,13 +1143,13 @@ if (data[1] == ' ') { i++; if (data[2] == ' ') { i++; } } } - /* looking at the hrule char */+ /* looking at the hrule uint8_t */ if (i + 2 >= size || !(data[i] == '~' || data[i] == '`')) return 0; c = data[i]; - /* the whole line must be the char or whitespace */+ /* the whole line must be the uint8_t or whitespace */ while (i < size && data[i] == c) { n++; i++; }@@ -1141,7 +1160,7 @@ if (syntax != NULL) { size_t syn = 0; - while (i < size && (data[i] == ' ' || data[i] == '\t'))+ while (i < size && data[i] == ' ') i++; syntax->data = data + i;@@ -1158,16 +1177,16 @@ /* strip all whitespace at the beginning and the end * of the {} block */- while (syn > 0 && isspace(syntax->data[0])) {+ while (syn > 0 && _isspace(syntax->data[0])) { syntax->data++; syn--; } - while (syn > 0 && isspace(syntax->data[syn - 1]))+ while (syn > 0 && _isspace(syntax->data[syn - 1])) syn--; i++; } else {- while (i < size && !isspace(data[i])) {+ while (i < size && !_isspace(data[i])) { syn++; i++; } }@@ -1176,7 +1195,7 @@ } while (i < size && data[i] != '\n') {- if (!isspace(data[i]))+ if (!_isspace(data[i])) return 0; i++;@@ -1187,7 +1206,7 @@ /* is_atxheader • returns whether the line is a hash-prefixed header */ static int-is_atxheader(struct sd_markdown *rndr, char *data, size_t size)+is_atxheader(struct sd_markdown *rndr, uint8_t *data, size_t size) { if (data[0] != '#') return 0;@@ -1198,7 +1217,7 @@ while (level < size && level < 6 && data[level] == '#') level++; - if (level < size && data[level] != ' ' && data[level] != '\t')+ if (level < size && data[level] != ' ') return 0; } @@ -1207,30 +1226,30 @@ /* is_headerline • returns whether the line is a setext-style hdr underline */ static int-is_headerline(char *data, size_t size)+is_headerline(uint8_t *data, size_t size) { size_t i = 0; /* test of level 1 header */ if (data[i] == '=') { for (i = 1; i < size && data[i] == '='; i++);- while (i < size && (data[i] == ' ' || data[i] == '\t')) i++;+ while (i < size && data[i] == ' ') i++; return (i >= size || data[i] == '\n') ? 1 : 0; } /* test of level 2 header */ if (data[i] == '-') { for (i = 1; i < size && data[i] == '-'; i++);- while (i < size && (data[i] == ' ' || data[i] == '\t')) i++;+ while (i < size && data[i] == ' ') i++; return (i >= size || data[i] == '\n') ? 2 : 0; } return 0; } static int-is_next_headerline(char *data, size_t size)+is_next_headerline(uint8_t *data, size_t size) { size_t i = 0;- + while (i < size && data[i] != '\n') i++; @@ -1242,32 +1261,36 @@ /* prefix_quote • returns blockquote prefix length */ static size_t-prefix_quote(char *data, size_t size)+prefix_quote(uint8_t *data, size_t size) { size_t i = 0; if (i < size && data[i] == ' ') i++; if (i < size && data[i] == ' ') i++; if (i < size && data[i] == ' ') i++;+ if (i < size && data[i] == '>') {- if (i + 1 < size && (data[i + 1] == ' ' || data[i+1] == '\t'))+ if (i + 1 < size && data[i + 1] == ' ') return i + 2;- else return i + 1; }- else return 0;++ return i + 1;+ }++ return 0; } /* prefix_code • returns prefix length for block code*/ static size_t-prefix_code(char *data, size_t size)+prefix_code(uint8_t *data, size_t size) {- if (size > 0 && data[0] == '\t') return 1; if (size > 3 && data[0] == ' ' && data[1] == ' '- && data[2] == ' ' && data[3] == ' ') return 4;+ && data[2] == ' ' && data[3] == ' ') return 4;+ return 0; } /* prefix_oli • returns ordered list item prefix */ static size_t-prefix_oli(char *data, size_t size)+prefix_oli(uint8_t *data, size_t size) { size_t i = 0; @@ -1281,9 +1304,7 @@ while (i < size && data[i] >= '0' && data[i] <= '9') i++; - if (i + 1 >= size ||- data[i] != '.' ||- (data[i + 1] != ' ' && data[i + 1] != '\t'))+ if (i + 1 >= size || data[i] != '.' || data[i + 1] != ' ') return 0; if (is_next_headerline(data + i, size - i))@@ -1294,7 +1315,7 @@ /* prefix_uli • returns ordered list item prefix */ static size_t-prefix_uli(char *data, size_t size)+prefix_uli(uint8_t *data, size_t size) { size_t i = 0; @@ -1302,9 +1323,9 @@ if (i < size && data[i] == ' ') i++; if (i < size && data[i] == ' ') i++; - if (i + 1 >= size || + if (i + 1 >= size || (data[i] != '*' && data[i] != '+' && data[i] != '-') ||- (data[i + 1] != ' ' && data[i + 1] != '\t'))+ data[i + 1] != ' ') return 0; if (is_next_headerline(data + i, size - i))@@ -1314,17 +1335,17 @@ } -/* parse_block • parsing of one block, returning next char to parse */+/* parse_block • parsing of one block, returning next uint8_t to parse */ static void parse_block(struct buf *ob, struct sd_markdown *rndr,- char *data, size_t size);+ uint8_t *data, size_t size); /* parse_blockquote • handles parsing of a blockquote fragment */ static size_t-parse_blockquote(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_blockquote(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t beg, end = 0, pre, work_size = 0;- char *work_data = 0;+ uint8_t *work_data = 0; struct buf *out = 0; out = rndr_newbuf(rndr, BUFFER_BLOCK);@@ -1362,15 +1383,15 @@ } static size_t-parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, int do_render);+parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, int do_render); /* parse_blockquote • handles parsing of a regular paragraph */ static size_t-parse_paragraph(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_paragraph(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t i = 0, end = 0; int level = 0;- struct buf work = { data, 0, 0, 0, 0 }; /* volatile working buffer */+ struct buf work = { data, 0, 0, 0 }; while (i < size) { for (end = i + 1; end < size && data[end - 1] != '\n'; end++) /* empty */;@@ -1446,11 +1467,11 @@ /* parse_fencedcode • handles parsing of a block-level code fragment */ static size_t-parse_fencedcode(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_fencedcode(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t beg, end; struct buf *work = 0;- struct buf lang = { 0, 0, 0, 0, 0 };+ struct buf lang = { 0, 0, 0, 0 }; beg = is_codefence(data, size, &lang); if (beg == 0) return 0;@@ -1489,7 +1510,7 @@ } static size_t-parse_blockcode(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_blockcode(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t beg, end, pre; struct buf *work = 0;@@ -1532,7 +1553,7 @@ /* parse_listitem • parsing of a single list item */ /* assuming initial prefix is already removed */ static size_t-parse_listitem(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, int *flags)+parse_listitem(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, int *flags) { struct buf *work = 0, *inter = 0; size_t beg = 0, end, pre, sublist = 0, orgpre = 0, i;@@ -1582,7 +1603,6 @@ i++; pre = i;- if (data[beg] == '\t') { i = 1; pre = 8; } /* checking for a new item */ if ((prefix_uli(data + beg + i, end - beg - i) &&@@ -1598,7 +1618,7 @@ sublist = work->size; } /* joining only indented stuff after empty lines */- else if (in_empty && i < 4 && data[beg] != '\t') {+ else if (in_empty && i < 4) { *flags |= MKD_LI_END; break; }@@ -1648,7 +1668,7 @@ /* parse_list • parsing ordered or unordered list block */ static size_t-parse_list(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, int flags)+parse_list(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, int flags) { struct buf *work = 0; size_t i = 0, j;@@ -1671,7 +1691,7 @@ /* parse_atxheader • parsing of atx-style headers */ static size_t-parse_atxheader(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_atxheader(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t level = 0; size_t i, end, skip;@@ -1679,7 +1699,7 @@ while (level < size && level < 6 && data[level] == '#') level++; - for (i = level; i < size && (data[i] == ' ' || data[i] == '\t'); i++);+ for (i = level; i < size && data[i] == ' '; i++); for (end = i; end < size && data[end] != '\n'; end++); skip = end;@@ -1687,7 +1707,7 @@ while (end && data[end - 1] == '#') end--; - while (end && (data[end - 1] == ' ' || data[end - 1] == '\t'))+ while (end && data[end - 1] == ' ') end--; if (end > i) {@@ -1708,13 +1728,13 @@ /* htmlblock_end • checking end of HTML block : </tag>[ \t]*\n[ \t*]\n */ /* returns the length on match, 0 otherwise */ static size_t-htmlblock_end(const char *tag, size_t tag_len, struct sd_markdown *rndr, char *data, size_t size)+htmlblock_end(const char *tag, size_t tag_len, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t i, w; /* checking if tag is a match */ if (tag_len + 3 >= size ||- strncasecmp(data + 2, tag, tag_len) != 0 ||+ strncasecmp((char *)data + 2, tag, tag_len) != 0 || data[tag_len + 2] != '>') return 0; @@ -1740,17 +1760,24 @@ /* parse_htmlblock • parsing of inline HTML block */ static size_t-parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, int do_render)+parse_htmlblock(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, int do_render) { size_t i, j = 0;- const char *curtag;+ const char *curtag = NULL; int found;- struct buf work = { data, 0, 0, 0, 0 };+ struct buf work = { data, 0, 0, 0 }; /* identification of the opening tag */- if (size < 2 || data[0] != '<') return 0;- curtag = find_block_tag(data + 1, size - 1);+ if (size < 2 || data[0] != '<')+ return 0; + i = 1;+ while (i < size && data[i] != '>' && data[i] != ' ')+ i++;++ if (i < size && data[i] == '>')+ curtag = find_block_tag((char *)data + 1, i - 1);+ /* handling of special cases */ if (!curtag) { @@ -1835,7 +1862,7 @@ } static void-parse_table_row(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, size_t columns, int *col_data)+parse_table_row(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, size_t columns, int *col_data) { size_t i = 0, col; struct buf *row_work = 0;@@ -1854,7 +1881,7 @@ cell_work = rndr_newbuf(rndr, BUFFER_SPAN); - while (i < size && isspace(data[i]))+ while (i < size && _isspace(data[i])) i++; cell_start = i;@@ -1864,7 +1891,7 @@ cell_end = i - 1; - while (cell_end > cell_start && isspace(data[cell_end]))+ while (cell_end > cell_start && _isspace(data[cell_end])) cell_end--; parse_inline(cell_work, rndr, data + cell_start, 1 + cell_end - cell_start);@@ -1875,7 +1902,7 @@ } for (; col < columns; ++col) {- struct buf empty_cell = {0, 0, 0, 0, 0};+ struct buf empty_cell = { 0, 0, 0, 0 }; rndr->cb.table_cell(row_work, &empty_cell, col_data[col], rndr->opaque); } @@ -1885,7 +1912,7 @@ } static size_t-parse_table_header(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size, size_t *columns, int **column_data)+parse_table_header(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size, size_t *columns, int **column_data) { int pipes; size_t i = 0, col, header_end, under_end;@@ -1923,7 +1950,7 @@ (*column_data)[col] |= MKD_TABLE_HEADER; - while (i < under_end && (data[i] == ' ' || data[i] == '\t'))+ while (i < under_end && data[i] == ' ') i++; if (data[i] == ':') {@@ -1940,7 +1967,7 @@ dashes++; } - while (i < under_end && (data[i] == ' ' || data[i] == '\t'))+ while (i < under_end && data[i] == ' ') i++; if (i < under_end && data[i] != '|')@@ -1960,7 +1987,7 @@ } static size_t-parse_table(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_table(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t i; @@ -2005,16 +2032,16 @@ return i; } -/* parse_block • parsing of one block, returning next char to parse */+/* parse_block • parsing of one block, returning next uint8_t to parse */ static void-parse_block(struct buf *ob, struct sd_markdown *rndr, char *data, size_t size)+parse_block(struct buf *ob, struct sd_markdown *rndr, uint8_t *data, size_t size) { size_t beg, end, i;- char *txt_data;+ uint8_t *txt_data; beg = 0; if (rndr->work_bufs[BUFFER_SPAN].size +- rndr->work_bufs[BUFFER_BLOCK].size > (int)rndr->max_nesting)+ rndr->work_bufs[BUFFER_BLOCK].size > rndr->max_nesting) return; while (beg < size) {@@ -2074,7 +2101,7 @@ /* is_ref • returns whether a line is a reference or not */ static int-is_ref(char *data, size_t beg, size_t end, size_t *last, struct link_ref **refs)+is_ref(const uint8_t *data, size_t beg, size_t end, size_t *last, struct link_ref **refs) { /* int n; */ size_t i = 0;@@ -2104,23 +2131,27 @@ i++; if (i >= end || data[i] != ':') return 0; i++;- while (i < end && (data[i] == ' ' || data[i] == '\t')) i++;+ while (i < end && data[i] == ' ') i++; if (i < end && (data[i] == '\n' || data[i] == '\r')) { i++; if (i < end && data[i] == '\r' && data[i - 1] == '\n') i++; }- while (i < end && (data[i] == ' ' || data[i] == '\t')) i++;+ while (i < end && data[i] == ' ') i++; if (i >= end) return 0; /* link: whitespace-free sequence, optionally between angle brackets */- if (data[i] == '<') i++;+ if (data[i] == '<')+ i++;+ link_offset = i;- while (i < end && data[i] != ' ' && data[i] != '\t'- && data[i] != '\n' && data[i] != '\r') i++;++ while (i < end && data[i] != ' ' && data[i] != '\n' && data[i] != '\r')+ i++;+ if (data[i - 1] == '>') link_end = i - 1; else link_end = i; /* optional spacer: (space | tab)* (newline | '\'' | '"' | '(' ) */- while (i < end && (data[i] == ' ' || data[i] == '\t')) i++;+ while (i < end && data[i] == ' ') i++; if (i < end && data[i] != '\n' && data[i] != '\r' && data[i] != '\'' && data[i] != '"' && data[i] != '(') return 0;@@ -2133,7 +2164,7 @@ /* optional (space|tab)* spacer after a newline */ if (line_end) { i = line_end + 1;- while (i < end && (data[i] == ' ' || data[i] == '\t')) i++; }+ while (i < end && data[i] == ' ') i++; } /* optional title: any non-newline sequence enclosed in '"() alone on its line */@@ -2149,7 +2180,7 @@ else title_end = i; /* stepping back */ i -= 1;- while (i > title_offset && (data[i] == ' ' || data[i] == '\t'))+ while (i > title_offset && data[i] == ' ') i -= 1; if (i > title_offset && (data[i] == '\'' || data[i] == '"' || data[i] == ')')) {@@ -2164,27 +2195,23 @@ *last = line_end; if (refs) {- char *title_str = NULL;- size_t title_size = 0;+ struct link_ref *ref; + ref = add_link_ref(refs, data + id_offset, id_end - id_offset);++ ref->link = bufnew(link_end - link_offset);+ bufput(ref->link, data + link_offset, link_end - link_offset);+ if (title_end > title_offset) {- title_str = data + title_offset;- title_size = title_end - title_offset;+ ref->title = bufnew(title_end - title_offset);+ bufput(ref->title, data + title_offset, title_end - title_offset); }-- add_link_ref( refs,- data + id_offset, /* identifier */- id_end - id_offset,- data + link_offset, /* link url */- link_end - link_offset,- title_str, /* title (optional) */- title_size); } return 1; } -static void expand_tabs(struct buf *ob, const char *line, size_t size)+static void expand_tabs(struct buf *ob, const uint8_t *line, size_t size) { size_t i = 0, tab = 0; @@ -2273,7 +2300,7 @@ } void-sd_markdown_render(struct buf *ob, const struct buf *ib, struct sd_markdown *md)+sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, struct sd_markdown *md) { static const float MARKDOWN_GROW_FACTOR = 1.4f; @@ -2285,28 +2312,28 @@ return; /* Preallocate enough space for our buffer to avoid expanding while copying */- bufgrow(text, ib->size);+ bufgrow(text, doc_size); /* reset the references table */ memset(&md->refs, 0x0, REF_TABLE_SIZE * sizeof(void *)); /* first pass: looking for references, copying everything else */ beg = 0;- while (beg < ib->size) /* iterating over lines */- if (is_ref(ib->data, beg, ib->size, &end, md->refs))+ while (beg < doc_size) /* iterating over lines */+ if (is_ref(document, beg, doc_size, &end, md->refs)) beg = end; else { /* skipping to the next line */ end = beg;- while (end < ib->size && ib->data[end] != '\n' && ib->data[end] != '\r')+ while (end < doc_size && document[end] != '\n' && document[end] != '\r') end++; /* adding the line body if present */ if (end > beg)- expand_tabs(text, ib->data + beg, end - beg);+ expand_tabs(text, document + beg, end - beg); - while (end < ib->size && (ib->data[end] == '\n' || ib->data[end] == '\r')) {+ while (end < doc_size && (document[end] == '\n' || document[end] == '\r')) { /* add one \n per newline */- if (ib->data[end] == '\n' || (end + 1 < ib->size && ib->data[end + 1] != '\n'))+ if (document[end] == '\n' || (end + 1 < doc_size && document[end + 1] != '\n')) bufputc(text, '\n'); end++; }
cbits/markdown.h view
@@ -60,35 +60,35 @@ /* sd_callbacks - functions for rendering parsed data */ struct sd_callbacks { /* block level callbacks - NULL skips the block */- void (*blockcode)(struct buf *ob, struct buf *text, struct buf *lang, void *opaque);- void (*blockquote)(struct buf *ob, struct buf *text, void *opaque);- void (*blockhtml)(struct buf *ob, struct buf *text, void *opaque);- void (*header)(struct buf *ob, struct buf *text, int level, void *opaque);+ void (*blockcode)(struct buf *ob, const struct buf *text, const struct buf *lang, void *opaque);+ void (*blockquote)(struct buf *ob, const struct buf *text, void *opaque);+ void (*blockhtml)(struct buf *ob,const struct buf *text, void *opaque);+ void (*header)(struct buf *ob, const struct buf *text, int level, void *opaque); void (*hrule)(struct buf *ob, void *opaque);- void (*list)(struct buf *ob, struct buf *text, int flags, void *opaque);- void (*listitem)(struct buf *ob, struct buf *text, int flags, void *opaque);- void (*paragraph)(struct buf *ob, struct buf *text, void *opaque);- void (*table)(struct buf *ob, struct buf *header, struct buf *body, void *opaque);- void (*table_row)(struct buf *ob, struct buf *text, void *opaque);- void (*table_cell)(struct buf *ob, struct buf *text, int flags, void *opaque);+ void (*list)(struct buf *ob, const struct buf *text, int flags, void *opaque);+ void (*listitem)(struct buf *ob, const struct buf *text, int flags, void *opaque);+ void (*paragraph)(struct buf *ob, const struct buf *text, void *opaque);+ void (*table)(struct buf *ob, const struct buf *header, const struct buf *body, void *opaque);+ void (*table_row)(struct buf *ob, const struct buf *text, void *opaque);+ void (*table_cell)(struct buf *ob, const struct buf *text, int flags, void *opaque); /* span level callbacks - NULL or return 0 prints the span verbatim */- int (*autolink)(struct buf *ob, struct buf *link, enum mkd_autolink type, void *opaque);- int (*codespan)(struct buf *ob, struct buf *text, void *opaque);- int (*double_emphasis)(struct buf *ob, struct buf *text, void *opaque);- int (*emphasis)(struct buf *ob, struct buf *text, void *opaque);- int (*image)(struct buf *ob, struct buf *link, struct buf *title, struct buf *alt, void *opaque);+ int (*autolink)(struct buf *ob, const struct buf *link, enum mkd_autolink type, void *opaque);+ int (*codespan)(struct buf *ob, const struct buf *text, void *opaque);+ int (*double_emphasis)(struct buf *ob, const struct buf *text, void *opaque);+ int (*emphasis)(struct buf *ob, const struct buf *text, void *opaque);+ int (*image)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *alt, void *opaque); int (*linebreak)(struct buf *ob, void *opaque);- int (*link)(struct buf *ob, struct buf *link, struct buf *title, struct buf *content, void *opaque);- int (*raw_html_tag)(struct buf *ob, struct buf *tag, void *opaque);- int (*triple_emphasis)(struct buf *ob, struct buf *text, void *opaque);- int (*strikethrough)(struct buf *ob, struct buf *text, void *opaque);- int (*superscript)(struct buf *ob, struct buf *text, void *opaque);+ int (*link)(struct buf *ob, const struct buf *link, const struct buf *title, const struct buf *content, void *opaque);+ int (*raw_html_tag)(struct buf *ob, const struct buf *tag, void *opaque);+ int (*triple_emphasis)(struct buf *ob, const struct buf *text, void *opaque);+ int (*strikethrough)(struct buf *ob, const struct buf *text, void *opaque);+ int (*superscript)(struct buf *ob, const struct buf *text, void *opaque); /* low level callbacks - NULL copies input directly into the output */- void (*entity)(struct buf *ob, struct buf *entity, void *opaque);- void (*normal_text)(struct buf *ob, struct buf *text, void *opaque);+ void (*entity)(struct buf *ob, const struct buf *entity, void *opaque);+ void (*normal_text)(struct buf *ob, const struct buf *text, void *opaque); /* header and footer */ void (*doc_header)(struct buf *ob, void *opaque);@@ -114,10 +114,10 @@ unsigned int extensions, size_t max_nesting, const struct sd_callbacks *callbacks,- void *opaque); + void *opaque); extern void-sd_markdown_render(struct buf *ob, const struct buf *ib, struct sd_markdown *md);+sd_markdown_render(struct buf *ob, const uint8_t *document, size_t doc_size, struct sd_markdown *md); extern void sd_markdown_free(struct sd_markdown *md);
cbits/stack.c view
@@ -57,7 +57,7 @@ if (!st->size) return NULL; - return st->item[st->size--];+ return st->item[--st->size]; } int
src/Text/Sundown/Buffer/Foreign.hsc view
@@ -2,25 +2,25 @@ module Text.Sundown.Buffer.Foreign ( Buffer (..)+ , getBufferData , c_bufnew , c_bufputs , c_bufgrow , c_bufrelease ) where -import Foreign-import Foreign.C.Types-import Foreign.C.String import Data.ByteString (ByteString) import qualified Data.ByteString as BS+import Foreign+import Foreign.C.String+import Foreign.C.Types #include "buffer.h" -data Buffer = Buffer { bufData :: ByteString- , bufSize :: Int- , bufASize :: Int- , bufUnit :: Int- , bufRef :: Int+data Buffer = Buffer { bufData :: CString+ , bufSize :: CSize+ , bufASize :: CSize+ , bufUnit :: CSize } instance Storable Buffer where@@ -29,14 +29,14 @@ peek ptr = do d <- (#peek struct buf, data) ptr s <- (#peek struct buf, size) ptr- dbs <- if d == nullPtr- then return $ BS.pack [0]- else BS.packCStringLen (d, s) as <- (#peek struct buf, asize) ptr u <- (#peek struct buf, unit) ptr- r <- (#peek struct buf, ref) ptr- return $ Buffer dbs s as u r+ return $ Buffer d s as u poke _ _ = error "Buffer.poke not implemented."++getBufferData :: Buffer -> IO ByteString+getBufferData (Buffer d s _ _) | d == nullPtr = return $ BS.pack [0]+ | otherwise = BS.packCStringLen (d, fromIntegral s) foreign import ccall "buffer.h bufnew" c_bufnew :: CSize -> IO (Ptr Buffer)
src/Text/Sundown/Markdown.hs view
@@ -8,8 +8,8 @@ -- | All 'Extensions' disabled noExtensions :: Extensions-noExtensions = Extensions False False False False False False +noExtensions = Extensions False False False False False False False False -- | All 'Extensions' enabled allExtensions :: Extensions-allExtensions = Extensions True True True True True True+allExtensions = Extensions True True True True True True True True
src/Text/Sundown/Markdown/Foreign.hsc view
@@ -9,20 +9,29 @@ ) where import Foreign+import Foreign.C.String import Foreign.C.Types- import Text.Sundown.Buffer.Foreign import Text.Sundown.Flag #include "markdown.h" -- | A set of switches to enable or disable markdown features.-data Extensions = Extensions { extNoIntraEmphasis :: Bool -- ^ Turn off underscores insode a word does designating emphasis.- , extTables :: Bool- , extFencedCode :: Bool -- ^ Turns on a non-indentation form of code-blocks, by blocking off a region with ~ or \`.- , extAutolink :: Bool -- ^ Turn things that look like URLs and email addresses into links- , extStrikethrough :: Bool -- ^ Surround text with `~` to designate it as struck through- , extLaxHtmlBlocks :: Bool -- ^ Allow HTML markup inside of paragraphs, instead requireing tags to be on separate lines+data Extensions = Extensions { extNoIntraEmphasis :: Bool -- ^ Turn off underscores insode a word+ -- does designating emphasis.+ , extTables :: Bool+ , extFencedCode :: Bool -- ^ Turns on a non-indentation form of+ -- code-blocks, by blocking off a regionwith ~+ -- or \`.+ , extAutolink :: Bool -- ^ Turn things that look like URLs and email+ -- addresses into links+ , extStrikethrough :: Bool -- ^ Surround text with `~` to designate it+ -- as struck through+ , extLaxHtmlBlocks :: Bool -- ^ Allow HTML markup inside of paragraphs,+ -- instead requireing tags to be on separate+ -- lines+ , extSpaceHeaders :: Bool+ , extSuperscript :: Bool } instance Flag Extensions where@@ -32,6 +41,8 @@ , (3, extAutolink exts) , (4, extStrikethrough exts) , (5, extLaxHtmlBlocks exts)+ , (6, extSpaceHeaders exts)+ , (7, extSuperscript exts) ] @@ -58,7 +69,7 @@ c_sd_markdown_new' :: CUInt -> CSize -> Ptr Callbacks -> Ptr () -> IO (Ptr Markdown) foreign import ccall "markdown.h sd_markdown_render"- c_sd_markdown_render :: Ptr Buffer -> Ptr Buffer -> Ptr Markdown -> IO ()+ c_sd_markdown_render :: Ptr Buffer -> CString -> CSize -> Ptr Markdown -> IO () foreign import ccall "markdown.h sd_markdown_free" c_sd_markdown_free :: Ptr Markdown -> IO ()
src/Text/Sundown/Renderers/Html.hs view
@@ -44,13 +44,17 @@ -- Do the markdown c_sdhtml_renderer callbacks options mode+ let maxNesting = fromIntegral $ fromMaybe defaultMaxNesting maxNestingM markdown <- c_sd_markdown_new exts maxNesting callbacks (castPtr options)- c_sd_markdown_render ob ib markdown++ Buffer {bufData = cs, bufSize = size} <- peek ib+ c_sd_markdown_render ob cs size markdown+ c_sd_markdown_free markdown -- Get the result- Buffer {bufData = output} <- peek ob+ output <- peek ob >>= getBufferData c_bufrelease ib c_bufrelease ob @@ -59,11 +63,11 @@ -- | All the 'HtmlRenderMode' disabled noHtmlModes :: HtmlRenderMode-noHtmlModes = HtmlRenderMode False False False False False False False False False False+noHtmlModes = HtmlRenderMode False False False False False False False False False -- | All the 'HtmlRenderMode' enabled allHtmlModes :: HtmlRenderMode-allHtmlModes = HtmlRenderMode True True True True True True True True True True+allHtmlModes = HtmlRenderMode True True True True True True True True True -- | Converts punctuation in Html entities, -- <http://daringfireball.net/projects/smartypants/>@@ -75,10 +79,11 @@ ib <- c_bufnew $ fromInteger . toInteger $ BS.length input c_bufputs ib input- - c_sdhtml_smartypants ob ib++ Buffer {bufData = cs, bufSize = size} <- peek ib+ c_sdhtml_smartypants ob cs size - Buffer {bufData = output} <- peek ob+ output <- peek ob >>= getBufferData c_bufrelease ib c_bufrelease ob
src/Text/Sundown/Renderers/Html/Foreign.hsc view
@@ -9,38 +9,39 @@ import Foreign+import Foreign.C.String import Foreign.C.Types- import Text.Sundown.Buffer.Foreign-import Text.Sundown.Markdown.Foreign import Text.Sundown.Flag+import Text.Sundown.Markdown.Foreign #include "html.h" -data HtmlRenderMode = HtmlRenderMode { htmlSkipHtml :: Bool -- ^ Drop in-line HTML tags from the output- , htmlSkipStyle :: Bool -- ^ Don't add any style tags to the output+data HtmlRenderMode = HtmlRenderMode { htmlSkipHtml :: Bool -- ^ Drop in-line HTML tags from the+ -- output+ , htmlSkipStyle :: Bool -- ^ Don't add any style tags to the+ -- output , htmlSkipImages :: Bool -- ^ Don't include images in the output , htmlSkipLinks :: Bool -- ^ Don't include links in the output , htmlExpandTabs :: Bool- , htmlSafelink :: Bool -- ^ Sanity check links for known URL schemes+ , htmlSafelink :: Bool -- ^ Sanity check links for known URL+ -- schemes , htmlToc :: Bool -- ^ Include a table of contents in the output , htmlHardWrap :: Bool- , htmlGithubBlockcode :: Bool , htmlUseXhtml :: Bool -- ^ Produce XHTML output instead of HTML } instance Flag HtmlRenderMode where- flagIndexes mode = [ (0, htmlSkipHtml mode)- , (1, htmlSkipStyle mode)- , (2, htmlSkipImages mode)- , (3, htmlSkipLinks mode)- , (5, htmlExpandTabs mode)- , (7, htmlSafelink mode)- , (8, htmlToc mode)- , (9, htmlHardWrap mode)- , (10, htmlGithubBlockcode mode)- , (11, htmlUseXhtml mode)+ flagIndexes mode = [ (0, htmlSkipHtml mode)+ , (1, htmlSkipStyle mode)+ , (2, htmlSkipImages mode)+ , (3, htmlSkipLinks mode)+ , (4, htmlExpandTabs mode)+ , (5, htmlSafelink mode)+ , (6, htmlToc mode)+ , (7, htmlHardWrap mode)+ , (8, htmlUseXhtml mode) ] data HtmlRenderOptions@@ -60,4 +61,4 @@ c_sdhtml_toc_renderer :: Ptr Callbacks -> Ptr HtmlRenderOptions -> IO () foreign import ccall "html.h sdhtml_smartypants"- c_sdhtml_smartypants :: Ptr Buffer -> Ptr Buffer -> IO ()+ c_sdhtml_smartypants :: Ptr Buffer -> CString -> CSize -> IO ()
sundown.cabal view
@@ -1,6 +1,6 @@ Cabal-version: >= 1.6 Name: sundown-Version: 0.2.3+Version: 0.3 Author: Francesco Mazzoli (f@mazzo.li) Maintainer: Francesco Mazzoli (f@mazzo.li) Build-Type: Simple@@ -36,14 +36,12 @@ , Text.Sundown.Flag , Text.Sundown.Markdown.Foreign - C-Sources: cbits/autolink.c, cbits/buffer.c, cbits/html.c,- cbits/html_smartypants.c, cbits/markdown.c,- cbits/stack.c+ C-Sources: cbits/autolink.c, cbits/buffer.c, cbits/houdini_href_e.c,+ cbits/houdini_html_e.c, cbits/html.c, cbits/html_smartypants.c,+ cbits/markdown.c, cbits/stack.c Include-Dirs: cbits - Includes: autolink.h, buffer.h, html.h, html_blocks.h, markdown.h,- stack.h+ Includes: autolink.h, buffer.h, html.h, html_blocks.h, markdown.h, stack.h - Install-includes: autolink.h, buffer.h, html.h, html_blocks.h, markdown.h,- stack.h+ Install-includes: autolink.h, buffer.h, houdini.h, html.h, html_blocks.h, markdown.h, stack.h