summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buffer.c57
-rw-r--r--src/buffer.h9
-rw-r--r--src/document.c5
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;
}
}
}