diff options
| -rw-r--r-- | Makefile.am | 3 | ||||
| -rw-r--r-- | src/content-parser.c | 271 | ||||
| -rw-r--r-- | src/directives.c | 62 | ||||
| -rw-r--r-- | src/directives.h | 36 | ||||
| -rw-r--r-- | src/error.c | 3 | ||||
| -rw-r--r-- | src/error.h | 1 | ||||
| -rw-r--r-- | tests/check_content_parser.c | 946 | 
7 files changed, 1304 insertions, 18 deletions
diff --git a/Makefile.am b/Makefile.am index d3ab12c..5ebb3bd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -34,6 +34,7 @@ BUILT_SOURCES = \  noinst_HEADERS = \  	src/content-parser.h \  	src/datetime-parser.h \ +	src/directives.h \  	src/file.h \  	src/error.h \  	src/loader.h \ @@ -74,6 +75,7 @@ check_PROGRAMS = \  libblogc_la_SOURCES = \  	src/content-parser.c \  	src/datetime-parser.c \ +	src/directives.c \  	src/file.c \  	src/error.c \  	src/loader.c \ @@ -326,6 +328,7 @@ tests_check_content_parser_CFLAGS = \  tests_check_content_parser_LDFLAGS = \  	-no-install \ +	-Wl,--wrap=blogc_directive_loader \  	$(NULL)  tests_check_content_parser_LDADD = \ diff --git a/src/content-parser.c b/src/content-parser.c index 0c99e31..0561d20 100644 --- a/src/content-parser.c +++ b/src/content-parser.c @@ -14,6 +14,7 @@  #include <string.h>  #include "content-parser.h" +#include "directives.h"  #include "utils.h"  // this is a half ass implementation of a markdown-like syntax. bugs are @@ -77,7 +78,7 @@ blogc_htmlentities(const char *str)  typedef enum {      CONTENT_START_LINE = 1, -    CONTENT_EXCERPT, +    CONTENT_EXCERPT_OR_DIRECTIVE,      CONTENT_EXCERPT_END,      CONTENT_HEADER,      CONTENT_HEADER_TITLE_START, @@ -98,6 +99,18 @@ typedef enum {      CONTENT_ORDERED_LIST_SPACE,      CONTENT_ORDERED_LIST_START,      CONTENT_ORDERED_LIST_END, +    CONTENT_DIRECTIVE_NAME_START, +    CONTENT_DIRECTIVE_NAME, +    CONTENT_DIRECTIVE_COLON, +    CONTENT_DIRECTIVE_ARGUMENT_START, +    CONTENT_DIRECTIVE_ARGUMENT, +    CONTENT_DIRECTIVE_PARAM_PREFIX_START, +    CONTENT_DIRECTIVE_PARAM_PREFIX, +    CONTENT_DIRECTIVE_PARAM_KEY_START, +    CONTENT_DIRECTIVE_PARAM_KEY, +    CONTENT_DIRECTIVE_PARAM_VALUE_START, +    CONTENT_DIRECTIVE_PARAM_VALUE, +    CONTENT_DIRECTIVE_PARAM_END,      CONTENT_PARAGRAPH,      CONTENT_PARAGRAPH_END,  } blogc_content_parser_state_t; @@ -480,6 +493,11 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **description)      char *parsed = NULL;      char *slug = NULL; +    char *directive_name = NULL; +    char *directive_argument = NULL; +    char *directive_key = NULL; +    sb_trie_t *directive_params = NULL; +      // this isn't empty because we need some reasonable default value in the      // unlikely case that we need to print some line ending before evaluating      // the "real" value. @@ -530,11 +548,9 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **description)                      break;                  start = current;                  if (c == '.') { -                    if (end_excerpt != NULL) { -                        eend = rv->len;  // fuck it -                        state = CONTENT_EXCERPT; -                        break; -                    } +                    eend = rv->len;  // fuck it +                    state = CONTENT_EXCERPT_OR_DIRECTIVE; +                    break;                  }                  if (c == '#') {                      header_level = 1; @@ -569,26 +585,31 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **description)                  state = CONTENT_PARAGRAPH;                  break; -            case CONTENT_EXCERPT: -                if (end_excerpt != NULL) { -                    if (c == '.') -                        break; -                    if (c == '\n' || c == '\r') { -                        state = CONTENT_EXCERPT_END; -                        break; +            case CONTENT_EXCERPT_OR_DIRECTIVE: +                if (c == '.') +                    break; +                if ((c == ' ' || c == '\t') && current - start == 2) { +                    state = CONTENT_DIRECTIVE_NAME_START; +                    if (is_last) { +                        state = CONTENT_PARAGRAPH; +                        continue;                      } +                    break; +                } +                if (c == '\n' || c == '\r') { +                    state = CONTENT_EXCERPT_END; +                    break;                  }                  eend = 0;                  state = CONTENT_PARAGRAPH;                  break;              case CONTENT_EXCERPT_END: -                if (end_excerpt != NULL) { -                    if (c == '\n' || c == '\r') { +                if (c == '\n' || c == '\r') { +                    if (end_excerpt != NULL)                          *end_excerpt = eend; -                        state = CONTENT_START_LINE; -                        break; -                    } +                    state = CONTENT_START_LINE; +                    break;                  }                  eend = 0;                  state = CONTENT_PARAGRAPH_END; @@ -1010,6 +1031,214 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **description)                  }                  break; +            case CONTENT_DIRECTIVE_NAME_START: +                if (is_last) { +                    state = CONTENT_PARAGRAPH; +                    continue; +                } +                if (c >= 'a' && c <= 'z') { +                    start2 = current; +                    state = CONTENT_DIRECTIVE_NAME; +                    break; +                } +                state = CONTENT_PARAGRAPH; +                break; + +            case CONTENT_DIRECTIVE_NAME: +                if (is_last) { +                    state = CONTENT_PARAGRAPH; +                    continue; +                } +                if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_') +                    break; +                if (c == ':') { +                    end = current; +                    state = CONTENT_DIRECTIVE_COLON; +                    break; +                } +                state = CONTENT_PARAGRAPH; +                break; + +            case CONTENT_DIRECTIVE_COLON: +                if (c == ':') { +                    free(directive_name); +                    directive_name = sb_strndup(src + start2, end - start2); +                    state = CONTENT_DIRECTIVE_ARGUMENT_START; +                    if (is_last) { +                        state = CONTENT_DIRECTIVE_PARAM_END; +                        continue; +                    } +                    break; +                } +                if (is_last) { +                    state = CONTENT_PARAGRAPH; +                    continue; +                } +                state = CONTENT_PARAGRAPH; +                break; + +            case CONTENT_DIRECTIVE_ARGUMENT_START: +                if (c == ' ' || c == '\t') { +                    if (is_last) { +                        state = CONTENT_DIRECTIVE_PARAM_END; +                        continue; +                    } +                    break; +                } +                if (c == '\n' || c == '\r' || is_last) { +                    state = CONTENT_DIRECTIVE_PARAM_PREFIX_START; +                    directive_argument = NULL; +                    if (is_last) { +                        state = CONTENT_DIRECTIVE_PARAM_END; +                        continue; +                    } +                    else +                        start2 = current + 1; +                    break; +                } +                start2 = current; +                state = CONTENT_DIRECTIVE_ARGUMENT; +                break; + +            case CONTENT_DIRECTIVE_ARGUMENT: +                if (c == '\n' || c == '\r' || is_last) { +                    state = CONTENT_DIRECTIVE_PARAM_PREFIX_START; +                    end = is_last && c != '\n' && c != '\r' ? src_len : +                        (real_end != 0 ? real_end : current); +                    free(directive_argument); +                    directive_argument = sb_strndup(src + start2, end - start2); +                    if (is_last) { +                        state = CONTENT_DIRECTIVE_PARAM_END; +                        continue; +                    } +                    else +                        start2 = current + 1; +                } +                break; + +            case CONTENT_DIRECTIVE_PARAM_PREFIX_START: +                if (is_last) { +                    state = CONTENT_PARAGRAPH; +                    continue; +                } +                if (c == ' ' || c == '\t') +                    break; +                if (c == '\n' || c == '\r') { +                    state = CONTENT_DIRECTIVE_PARAM_END; +                    continue; +                } +                prefix = sb_strndup(src + start2, current - start2); +                state = CONTENT_DIRECTIVE_PARAM_PREFIX; +                current--; +                break; + +            case CONTENT_DIRECTIVE_PARAM_PREFIX: +                if (c == ' ' || c == '\t') +                    break; +                if (c == ':' && sb_str_starts_with(src + start2, prefix)) { +                    state = CONTENT_DIRECTIVE_PARAM_KEY_START; +                    break; +                } +                state = CONTENT_PARAGRAPH; +                if (is_last) +                    continue; +                break; + +            case CONTENT_DIRECTIVE_PARAM_KEY_START: +                if (is_last) { +                    state = CONTENT_PARAGRAPH; +                    continue; +                } +                if (c >= 'a' && c <= 'z') { +                    start2 = current; +                    state = CONTENT_DIRECTIVE_PARAM_KEY; +                    break; +                } +                state = CONTENT_PARAGRAPH; +                break; + +            case CONTENT_DIRECTIVE_PARAM_KEY: +                if (is_last) { +                    state = CONTENT_PARAGRAPH; +                    continue; +                } +                if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '_') +                    break; +                if (c == ':') { +                    free(directive_key); +                    directive_key = sb_strndup(src + start2, current - start2); +                    state = CONTENT_DIRECTIVE_PARAM_VALUE_START; +                    break; +                } +                state = CONTENT_PARAGRAPH; +                break; + +            case CONTENT_DIRECTIVE_PARAM_VALUE_START: +                if (is_last) { +                    state = CONTENT_PARAGRAPH; +                    continue; +                } +                if (c == ' ' || c == '\t') +                    break; +                start2 = current; +                state = CONTENT_DIRECTIVE_PARAM_VALUE; +                break; + +            case CONTENT_DIRECTIVE_PARAM_VALUE: +                if (c == '\n' || c == '\r' || is_last) { +                    state = CONTENT_DIRECTIVE_PARAM_END; +                    end = is_last && c != '\n' && c != '\r' ? src_len : +                        (real_end != 0 ? real_end : current); +                    if (directive_params == NULL) +                        directive_params = sb_trie_new(free); +                    sb_trie_insert(directive_params, directive_key, +                        sb_strndup(src + start2, end - start2)); +                    free(directive_key); +                    directive_key = NULL; +                    if (!is_last) +                        start2 = current + 1; +                } +                if (!is_last) +                    break; + +            case CONTENT_DIRECTIVE_PARAM_END: +                if (c == '\n' || c == '\r' || is_last) { +                    // FIXME: handle errors in the rest of the parser. +                    blogc_error_t *err = NULL; +                    blogc_directive_ctx_t *ctx = sb_malloc( +                        sizeof(blogc_directive_ctx_t)); +                    ctx->name = directive_name; +                    ctx->argument = directive_argument; +                    ctx->params = directive_params; +                    ctx->eol = line_ending; +                    char *rv_d = blogc_directive_loader(ctx, &err); +                    free(ctx); +                    blogc_error_print(err); +                    if (rv_d != NULL) +                        sb_string_append(rv, rv_d); +                    free(rv_d); +                    state = CONTENT_START_LINE; +                    start = current; +                    free(directive_name); +                    directive_name = NULL; +                    free(directive_argument); +                    directive_argument = NULL; +                    sb_trie_free(directive_params); +                    directive_params = NULL; +                    free(prefix); +                    prefix = NULL; +                    break; +                } +                if (c == ' ' || c == '\t') { +                    start2 = current; +                    state = CONTENT_DIRECTIVE_PARAM_PREFIX; +                    break; +                } +                state = CONTENT_PARAGRAPH; +                if (is_last) +                    continue; +                break; +              case CONTENT_PARAGRAPH:                  if (c == '\n' || c == '\r' || is_last) {                      state = CONTENT_PARAGRAPH_END; @@ -1043,5 +1272,11 @@ blogc_content_parse(const char *src, size_t *end_excerpt, char **description)          current++;      } +    free(directive_name); +    free(directive_argument); +    free(directive_key); +    sb_trie_free(directive_params); +    free(prefix); +      return sb_string_free(rv, false);  } diff --git a/src/directives.c b/src/directives.c new file mode 100644 index 0000000..65d2e7b --- /dev/null +++ b/src/directives.c @@ -0,0 +1,62 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2015 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif /* HAVE_CONFIG_H */ + +#include <string.h> + +#include "directives.h" +#include "error.h" +#include "utils.h" + + +const static blogc_directive_t registry[] = { +    {"youtube", blogc_directive_youtube}, +    {NULL, NULL}, +}; + + +char* +blogc_directive_loader(blogc_directive_ctx_t *ctx, blogc_error_t **err) +{ +    if (ctx == NULL) +        return NULL; +    if (err == NULL || *err != NULL) +        return NULL; +    for (unsigned int i = 0; registry[i].name != NULL; i++) +        if (0 == strcmp(ctx->name, registry[i].name)) +            return registry[i].callback(ctx, err); +    *err = blogc_error_new_printf(BLOGC_WARNING_CONTENT_PARSER, +        "Directive not found: %s", ctx->name); +    return NULL; +} + + +static char* +blogc_directive_youtube(blogc_directive_ctx_t *ctx, blogc_error_t **err) +{ +    if (ctx->argument == NULL) { +        *err = blogc_error_new_printf(BLOGC_WARNING_CONTENT_PARSER, +            "youtube: video ID must be provided as argument"); +        return NULL; +    } + +    char *width = sb_trie_lookup(ctx->params, "width"); +    char *height = sb_trie_lookup(ctx->params, "height"); + +    // using default 16:9 sizes provided by youtube as of 2015-11-04 +    return sb_strdup_printf( +        "<iframe width=\"%s\" height=\"%s\" " +        "src=\"https://www.youtube.com/embed/%s\" frameborder=\"0\" " +        "allowfullscreen></iframe>%s", +        width == NULL ? "560" : width, +        height == NULL ? "315" : height, +        ctx->argument, ctx->eol); +} diff --git a/src/directives.h b/src/directives.h new file mode 100644 index 0000000..de1cb55 --- /dev/null +++ b/src/directives.h @@ -0,0 +1,36 @@ +/* + * blogc: A blog compiler. + * Copyright (C) 2015 Rafael G. Martins <rafael@rafaelmartins.eng.br> + * + * This program can be distributed under the terms of the BSD License. + * See the file LICENSE. + */ + +#ifndef _DIRECTIVES_H +#define _DIRECTIVES_H + +#include "utils.h" +#include "error.h" + +typedef struct { +    const char *name; +    const char *argument; +    sb_trie_t *params; +    const char *eol; +} blogc_directive_ctx_t; + +typedef char* (*blogc_directive_func_t)(blogc_directive_ctx_t *ctx, +    blogc_error_t **err); + +typedef struct { +    const char *name; +    blogc_directive_func_t callback; +} blogc_directive_t; + +char* blogc_directive_loader(blogc_directive_ctx_t *ctx, blogc_error_t **err); + + +// built-in directives (that are everything we support right now +static char* blogc_directive_youtube(blogc_directive_ctx_t *ctx, blogc_error_t **err); + +#endif /* _DIRECTIVES_H */ diff --git a/src/error.c b/src/error.c index 586386a..3aea641 100644 --- a/src/error.c +++ b/src/error.c @@ -125,6 +125,9 @@ blogc_error_print(blogc_error_t *err)          case BLOGC_WARNING_DATETIME_PARSER:              fprintf(stderr, "blogc: warning: datetime: %s\n", err->msg);              break; +        case BLOGC_WARNING_CONTENT_PARSER: +            fprintf(stderr, "blogc: warning: content: %s\n", err->msg); +            break;          default:              fprintf(stderr, "blogc: error: %s\n", err->msg);      } diff --git a/src/error.h b/src/error.h index caa86b0..886d7d3 100644 --- a/src/error.h +++ b/src/error.h @@ -17,6 +17,7 @@ typedef enum {      BLOGC_ERROR_TEMPLATE_PARSER,      BLOGC_ERROR_LOADER,      BLOGC_WARNING_DATETIME_PARSER, +    BLOGC_WARNING_CONTENT_PARSER,  } blogc_error_type_t;  typedef struct { diff --git a/tests/check_content_parser.c b/tests/check_content_parser.c index 2444ebb..4f201d1 100644 --- a/tests/check_content_parser.c +++ b/tests/check_content_parser.c @@ -16,6 +16,7 @@  #include <cmocka.h>  #include <string.h>  #include "../src/content-parser.h" +#include "../src/directives.h"  #include "../src/utils.h" @@ -1095,6 +1096,764 @@ test_content_parse_ordered_list_crlf(void **state)  } +char* +__wrap_blogc_directive_loader(blogc_directive_ctx_t *ctx, blogc_error_t **err) +{ +    assert_non_null(err); +    assert_null(*err); +    assert_string_equal(ctx->name, mock_type(const char*)); +    const char *arg = mock_type(const char*); +    if (arg == NULL) +        assert_null(ctx->argument); +    else +        assert_string_equal(ctx->argument, arg); +    assert_int_equal(sb_trie_size(ctx->params), mock_type(unsigned int)); + +    for (unsigned int i = 0; i < sb_trie_size(ctx->params); i++) { +        const char *key = mock_type(const char*); +        const char *value = mock_type(const char*); +        assert_string_equal(sb_trie_lookup(ctx->params, key), value); +    } + +    return sb_strdup("CHUNDA\n"); +} + + +static void +test_content_parse_directive(void **state) +{ +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    char *html = blogc_content_parse( +        ".. bola::", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        ".. bola::\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        ".. bola:: ", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        ".. bola:: \n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        ".. bola::\r\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    html = blogc_content_parse( +        ".. bola::\n" +        "   :asd: qwe", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    html = blogc_content_parse( +        ".. bola::\n" +        "   :asd: qwe\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    html = blogc_content_parse( +        ".. bola::\r\n" +        "\t:asd: qwe\r\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    will_return(__wrap_blogc_directive_loader, "vbn"); +    html = blogc_content_parse( +        ".. bola::\n" +        "\t\t:asd: qwe\n" +        "\t\t:zxc: vbn", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    will_return(__wrap_blogc_directive_loader, "vbn"); +    html = blogc_content_parse( +        ".. bola::\n" +        " :asd: qwe\n" +        " :zxc: vbn\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    will_return(__wrap_blogc_directive_loader, "vbn"); +    html = blogc_content_parse( +        ".. bola::\r\n" +        "   :asd: qwe\r\n" +        "   :zxc: vbn\r\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 3); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "ert"); +    will_return(__wrap_blogc_directive_loader, "zxvc"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "   :ert: zxvc\n" +        "   :qwe: bola\n" +        "\n" +        "bola", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "<p>bola</p>\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 3); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "ert"); +    will_return(__wrap_blogc_directive_loader, "zxvc"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    html = blogc_content_parse( +        "# foo\r\n" +        "\r\n" +        ".. bola::\r\n" +        "   :asd: qwe\r\n" +        "   :ert: zxvc\r\n" +        "   :qwe: bola\r\n" +        "\r\n" +        "bola", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\r\n" +        "CHUNDA\n" +        "<p>bola</p>\r\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola::\n" +        "\n" +        ".. bola::", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, 0); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola:: asd\n" +        "\n" +        ".. bola:: asd\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        "# foo\r\n" +        "\r\n" +        ".. bola::\r\n" +        "\r\n" +        ".. bola::\r\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\r\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "\n" +        ".. bola::", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola:: asd\n" +        "   :asd: qwe\n" +        "\n" +        ".. bola:: asd\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "\n" +        ".. bola::\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        "# foo\r\n" +        "\r\n" +        ".. bola::\r\n" +        "   :asd: qwe\r\n" +        "\r\n" +        ".. bola::\r\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\r\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "\n" +        ".. bola::\n" +        "   :asd: zxc\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    html = blogc_content_parse( +        "# foo\r\n" +        "\r\n" +        ".. bola::\r\n" +        "   :asd: qwe\r\n" +        "\r\n" +        ".. bola::\r\n" +        "   :asd: zxc\r\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\r\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "123"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "456"); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "   :qwe: 123\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "   :qwe: 456", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "123"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "456"); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola:: asd\n" +        "   :asd: qwe\n" +        "   :qwe: 123\n" +        "\n" +        ".. bola:: asd\n" +        "   :asd: qwe\n" +        "   :qwe: 456\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "123"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "456"); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "   :qwe: 123\n" +        "\n" +        ".. bola::\n" +        "   :asd: qwe\n" +        "   :qwe: 456\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "123"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, NULL); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "456"); +    html = blogc_content_parse( +        "# foo\r\n" +        "\r\n" +        ".. bola::\r\n" +        "   :asd: qwe\r\n" +        "   :qwe: 123\r\n" +        "\r\n" +        ".. bola::\r\n" +        "   :asd: qwe\r\n" +        "   :qwe: 456\r\n", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\r\n" +        "CHUNDA\n" +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        ".. bola:: chunda", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        ".. bola:: chunda\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 0); +    html = blogc_content_parse( +        ".. bola:: chunda\r\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    html = blogc_content_parse( +        ".. bola:: chunda\n" +        "   :asd: qwe", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    html = blogc_content_parse( +        ".. bola:: chunda\n" +        "   :asd: qwe\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 1); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    html = blogc_content_parse( +        ".. bola:: chunda\r\n" +        "   :asd: qwe\r\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    will_return(__wrap_blogc_directive_loader, "vbn"); +    html = blogc_content_parse( +        ".. bola:: chunda\n" +        "   :asd: qwe\n" +        "   :zxc: vbn", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    will_return(__wrap_blogc_directive_loader, "vbn"); +    html = blogc_content_parse( +        ".. bola:: chunda\n" +        "   :asd: qwe\n" +        "   :zxc: vbn\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "zxc"); +    will_return(__wrap_blogc_directive_loader, "vbn"); +    html = blogc_content_parse( +        ".. bola:: chunda\r\n" +        "   :asd: qwe\r\n" +        "   :zxc: vbn\r\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "CHUNDA\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 3); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "ert"); +    will_return(__wrap_blogc_directive_loader, "zxvc"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    html = blogc_content_parse( +        "# foo\n" +        "\n" +        ".. bola:: chunda\n" +        "   :asd: qwe\n" +        "   :ert: zxvc\n" +        "   :qwe: bola\n" +        "\n" +        "bola", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\n" +        "CHUNDA\n" +        "<p>bola</p>\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 3); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "ert"); +    will_return(__wrap_blogc_directive_loader, "zxvc"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    html = blogc_content_parse( +        "# foo\r\n" +        "\r\n" +        ".. bola:: chunda\r\n" +        "   :asd: qwe\r\n" +        "   :ert: zxvc\r\n" +        "   :qwe: bola\r\n" +        "\r\n" +        "bola", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\r\n" +        "CHUNDA\n" +        "<p>bola</p>\r\n"); +    free(html); + +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "chunda"); +    will_return(__wrap_blogc_directive_loader, 3); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "ert"); +    will_return(__wrap_blogc_directive_loader, "zxvc"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "bola"); +    will_return(__wrap_blogc_directive_loader, "bolao"); +    will_return(__wrap_blogc_directive_loader, "chund"); +    will_return(__wrap_blogc_directive_loader, 2); +    will_return(__wrap_blogc_directive_loader, "asd"); +    will_return(__wrap_blogc_directive_loader, "qwe"); +    will_return(__wrap_blogc_directive_loader, "ert"); +    will_return(__wrap_blogc_directive_loader, "zxvc"); +    html = blogc_content_parse( +        "# foo\r\n" +        "\r\n" +        ".. bola:: chunda\r\n" +        "   :asd: qwe\r\n" +        "   :ert: zxvc\r\n" +        "   :qwe: bola\r\n" +        "\r\n" +        ".. bolao:: chund\r\n" +        "    :asd: qwe\r\n" +        "    :ert: zxvc\r\n" +        "\r\n" +        "bola", NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<h1 id=\"foo\">foo</h1>\r\n" +        "CHUNDA\n" +        "CHUNDA\n" +        "<p>bola</p>\r\n"); +    free(html); +} + +  static void  test_content_parse_description(void **state)  { @@ -1596,6 +2355,191 @@ test_content_parse_invalid_ordered_list(void **state)  static void +test_content_parse_invalid_directive(void **state) +{ +    char *html = blogc_content_parse( +        ".. ", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. </p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. \n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. </p>\n"); +    free(html); + +    html = blogc_content_parse( +        "..  ", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>..  <br /></p>\n"); +    free(html); + +    html = blogc_content_parse( +        "..  \n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>..  <br /></p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. a", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. a</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. a\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. a</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd:", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd:</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd:\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd:</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :a", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :a</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :a\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :a</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :as", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :as</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :as\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :as</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :as:", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :as:</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :as:\n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :as:</p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :as: ", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :as: </p>\n"); +    free(html); + +    html = blogc_content_parse( +        ".. asd::\n" +        "    :as: \n", +        NULL, NULL); +    assert_non_null(html); +    assert_string_equal(html, +        "<p>.. asd::\n" +        "    :as: </p>\n"); +    free(html); +} + + +static void  test_content_parse_inline(void **state)  {      char *html = blogc_content_parse_inline( @@ -2038,6 +2982,7 @@ main(void)          unit_test(test_content_parse_unordered_list_crlf),          unit_test(test_content_parse_ordered_list),          unit_test(test_content_parse_ordered_list_crlf), +        unit_test(test_content_parse_directive),          unit_test(test_content_parse_description),          unit_test(test_content_parse_description_crlf),          unit_test(test_content_parse_invalid_excerpt), @@ -2048,6 +2993,7 @@ main(void)          unit_test(test_content_parse_invalid_horizontal_rule),          unit_test(test_content_parse_invalid_unordered_list),          unit_test(test_content_parse_invalid_ordered_list), +        unit_test(test_content_parse_invalid_directive),          unit_test(test_content_parse_inline),          unit_test(test_content_parse_inline_em),          unit_test(test_content_parse_inline_strong),  | 
