diff --git a/config b/config index e0d7ccd..d8fa0ae 100644 --- a/config +++ b/config @@ -1,6 +1,6 @@ # vim:ft=sh: ngx_addon_name=ngx_http_awesomeindex_module -ngx_module_libs="-lmarkdown" +ngx_module_libs="-lmd4c-html" if [ "$ngx_module_link" = DYNAMIC ] ; then ngx_module_type=HTTP diff --git a/ngx_http_awesomeindex_module.c b/ngx_http_awesomeindex_module.c index c6e4385..5ebfad9 100644 --- a/ngx_http_awesomeindex_module.c +++ b/ngx_http_awesomeindex_module.c @@ -22,10 +22,10 @@ #include #include #include +#include "ngx_buf.h" #include "ngx_string.h" -#include - +#include "md4c-html.h" #include "template.h" #if defined(__GNUC__) && (__GNUC__ >= 3) @@ -328,7 +328,85 @@ ngx_awesomeindex_conf_set_headerfooter(ngx_conf_t *cf, ngx_command_t *cmd, void #define ngx_has_flag(_where, _what) \ (((_where) & (_what)) == (_what)) +/********************************* + *** Simple grow-able buffer *** + *********************************/ +/* We render to a memory buffer instead of directly outputting the rendered + * documents, as this allows using this utility for evaluating performance + * of MD4C (--stat option). This allows us to measure just time of the parser, + * without the I/O. + */ + +struct membuffer { + char* data; + size_t asize; + size_t size; + u_char fail; +}; + +static u_char +membuf_init(struct membuffer* buf, MD_SIZE new_asize) +{ + buf->size = 0; + buf->asize = new_asize; + buf->data = malloc(buf->asize); + if(buf->data == NULL) { + buf->fail = 1; + return 1; + } + buf->fail = 0; + return 0; +} + +static void +membuf_free(struct membuffer* buf) +{ + if(buf && buf->data) free(buf->data); +} + +static void +membuf_grow(struct membuffer* buf, size_t new_asize) +{ + buf->data = realloc(buf->data, new_asize); + if(buf->data == NULL) { + buf->fail = 1; + } + buf->asize = new_asize; +} + +static void +membuf_append(struct membuffer* buf, const char* data, MD_SIZE size) +{ + if(buf->asize < buf->size + size) + membuf_grow(buf, buf->size + buf->size / 2 + size); + memcpy(buf->data + buf->size, data, size); + buf->size += size; +} + +static void +process_md_output(const MD_CHAR* text, MD_SIZE size, void* userdata) +{ + struct membuffer *buf = (struct membuffer*) userdata; + if (!buf->fail) membuf_append(buf, text, size); +} + +static ssize_t ngx_awesomeindex_read_file(ngx_http_request_t *r, u_char* filename, size_t file_len, u_char* dest) +{ + ngx_file_t file; + ngx_memzero(&file, sizeof(ngx_file_t)); + file.fd = ngx_open_file(filename, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); + if (file.fd == NGX_INVALID_FILE) { + ngx_log_error(NGX_LOG_ALERT, r->connection->log, ngx_errno, + "cannot open readme file \"%V\"", filename); + return NGX_ERROR; + } + file.log = r->connection->log; + + ssize_t n = ngx_read_file(&file, dest, file_len, 0); + ngx_close_file(file.fd); + return n; +} typedef struct { @@ -559,11 +637,21 @@ static const ngx_str_t img_icon_pre = ngx_string("\"\""); -static const ngx_str_t footer_pre = +static const ngx_str_t footer_md_pre = ngx_string("