diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buffer.c | 57 | ||||
-rw-r--r-- | src/buffer.h | 9 | ||||
-rw-r--r-- | src/document.c | 5 |
3 files changed, 67 insertions, 4 deletions
diff --git a/src/buffer.c b/src/buffer.c index 2ca0fd1..af77b70 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -62,6 +62,13 @@ hoedown_buffer_init( buf->buffer_free = buffer_free; } +void +hoedown_buffer_uninit(hoedown_buffer *buf) +{ + assert(buf && buf->unit); + buf->data_free(buf->data); +} + hoedown_buffer * hoedown_buffer_new(size_t unit) { @@ -74,6 +81,7 @@ void hoedown_buffer_free(hoedown_buffer *buf) { if (!buf) return; + assert(buf && buf->unit); buf->data_free(buf->data); @@ -138,6 +146,19 @@ hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c) buf->size += 1; } +int +hoedown_buffer_putf(hoedown_buffer *buf, FILE *file) +{ + assert(buf && buf->unit); + + while (!(feof(file) || ferror(file))) { + hoedown_buffer_grow(buf, buf->size + buf->unit); + buf->size += fread(buf->data + buf->size, 1, buf->unit, file); + } + + return ferror(file); +} + void hoedown_buffer_set(hoedown_buffer *buf, const uint8_t *data, size_t size) { @@ -174,8 +195,6 @@ hoedown_buffer_prefix(const hoedown_buffer *buf, const char *prefix) { size_t i; - assert(buf && buf->unit); - for (i = 0; i < buf->size; ++i) { if (prefix[i] == 0) return 0; @@ -253,3 +272,37 @@ hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...) buf->size += n; } + +void hoedown_buffer_put_utf8(hoedown_buffer *buf, unsigned int c) { + unsigned char unichar[4]; + + assert(buf && buf->unit); + + if (c < 0x80) { + hoedown_buffer_putc(buf, c); + } + else if (c < 0x800) { + unichar[0] = 192 + (c / 64); + unichar[1] = 128 + (c % 64); + hoedown_buffer_put(buf, unichar, 2); + } + else if (c - 0xd800u < 0x800) { + HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd"); + } + else if (c < 0x10000) { + unichar[0] = 224 + (c / 4096); + unichar[1] = 128 + (c / 64) % 64; + unichar[2] = 128 + (c % 64); + hoedown_buffer_put(buf, unichar, 3); + } + else if (c < 0x110000) { + unichar[0] = 240 + (c / 262144); + unichar[1] = 128 + (c / 4096) % 64; + unichar[2] = 128 + (c / 64) % 64; + unichar[3] = 128 + (c % 64); + hoedown_buffer_put(buf, unichar, 4); + } + else { + HOEDOWN_BUFPUTSL(buf, "\xef\xbf\xbd"); + } +} diff --git a/src/buffer.h b/src/buffer.h index fcda83c..d7703f8 100644 --- a/src/buffer.h +++ b/src/buffer.h @@ -59,6 +59,9 @@ void hoedown_buffer_init( hoedown_free_callback buffer_free ); +/* hoedown_buffer_uninit: uninitialize an existing buffer */ +void hoedown_buffer_uninit(hoedown_buffer *buf); + /* hoedown_buffer_new: allocate a new buffer */ hoedown_buffer *hoedown_buffer_new(size_t unit) __attribute__ ((malloc)); @@ -77,6 +80,9 @@ void hoedown_buffer_puts(hoedown_buffer *buf, const char *str); /* hoedown_buffer_putc: append a single char to a buffer */ void hoedown_buffer_putc(hoedown_buffer *buf, uint8_t c); +/* hoedown_buffer_putf: read from a file and append to a buffer, until EOF or error */ +int hoedown_buffer_putf(hoedown_buffer *buf, FILE* file); + /* hoedown_buffer_set: replace the buffer's contents with raw data */ void hoedown_buffer_set(hoedown_buffer *buf, const uint8_t *data, size_t size); @@ -101,6 +107,9 @@ const char *hoedown_buffer_cstr(hoedown_buffer *buf); /* hoedown_buffer_printf: formatted printing to a buffer */ void hoedown_buffer_printf(hoedown_buffer *buf, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); +/* hoedown_buffer_put_utf8: put a Unicode character encoded as UTF-8 */ +void hoedown_buffer_put_utf8(hoedown_buffer *buf, unsigned int codepoint); + /* hoedown_buffer_free: free the buffer */ void hoedown_buffer_free(hoedown_buffer *buf); diff --git a/src/document.c b/src/document.c index 17feb24..27c17b2 100644 --- a/src/document.c +++ b/src/document.c @@ -459,7 +459,7 @@ tag_length(uint8_t *data, size_t size, hoedown_autolink_type *autolink) static void parse_inline(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t size) { - size_t i = 0, end = 0; + size_t i = 0, end = 0, consumed = 0; hoedown_buffer work = { 0, 0, 0, 0, NULL, NULL, NULL }; uint8_t *active_char = doc->active_char; @@ -483,12 +483,13 @@ parse_inline(hoedown_buffer *ob, hoedown_document *doc, uint8_t *data, size_t si if (end >= size) break; i = end; - end = markdown_char_ptrs[ (int)active_char[data[end]] ](ob, doc, data + i, i, size - i); + end = markdown_char_ptrs[ (int)active_char[data[end]] ](ob, doc, data + i, i - consumed, size - i); if (!end) /* no action from the callback */ end = i + 1; else { i += end; end = i; + consumed = i; } } } |