diff --git a/src/include/mdutil.h b/src/include/mdutil.h index af1a4c6..8b119fd 100644 --- a/src/include/mdutil.h +++ b/src/include/mdutil.h @@ -54,5 +54,7 @@ struct linedata { void identifyline(char *line, struct linedata *prev, struct linedata *ret); /* prev is almost never used, but sometimes it is. */ char *realcontent(char *line, struct linedata *data); +int isgenerictag(char *text); +/* Identifies open and close tags */ #endif diff --git a/src/inlines.c b/src/inlines.c index 817a9d3..e505c33 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -19,6 +19,7 @@ #include #include +#include #include static const char *punctuation = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~"; @@ -38,12 +39,15 @@ static int writelink(char *data, int i, size_t len, FILE *out); static int writeimage(char *data, int i, size_t len, FILE *out); static int writeautolink(char *data, int i, size_t len, FILE *out); static int writehardbreak(char *data, int i, size_t len, FILE *out); +static int writerawhtml(char *data, int i, size_t len, FILE *out); static int getlinkinfo(char *data, int i, size_t len, int *textstart, int *textend, int *titlestart, int *titleend, int *linkstart, int *linkend); static void writeescaped(char *data, size_t len, FILE *out); static void writechescape(char c, FILE *out); +static int inlinehtmlcase(char *data, char *start, char *end, FILE *out); +/* Returns length of raw html */ void writeline(char *data, FILE *out) { writedata(data, strlen(data), out); @@ -63,6 +67,8 @@ void writedata(char *data, size_t len, FILE *out) { goto special; if ((newi = writehardbreak(data, i, len, out)) >= 0) goto special; + if ((newi = writerawhtml(data, i, len, out)) >= 0) + goto special; if (data[i] == '\\') { if (strchr(punctuation, data[i + 1]) == NULL) writechescape('\\', out); @@ -202,6 +208,48 @@ static int writehardbreak(char *data, int i, size_t len, FILE *out) { return i + codelen; } +static int writerawhtml(char *data, int i, size_t len, FILE *out) { + int taglen; + data += i; + taglen = isgenerictag(data); + if (taglen > 0) { + fwrite(data, 1, taglen, out); + return i + taglen; + } + + if (memcmp(data, ""); + if (end == NULL) + goto notcomment; + taglen = end - text; + if (text[0] == '>' || memcmp(text, "->", 2) == 0) + goto notcomment; + if (text[taglen - 1] == '-') { + goto notcomment; + } + for (j = 0; j < taglen - 1; ++j) { + if (memcmp(text + j, "--", 2) == 0) + goto notcomment; + } + + fwrite(data, 1, taglen + 7, out); + + return i + taglen + 7; + } +notcomment: + if ((taglen = inlinehtmlcase(data, "", out)) > 0) + return i + taglen; + if ((taglen = inlinehtmlcase(data, "", out)) > 0) + return i + taglen; + if ((taglen = inlinehtmlcase(data, "", out)) > 0) + return i + taglen; + + return -1; +} + static int getlinkinfo(char *data, int i, size_t len, int *textstart, int *textend, int *titlestart, int *titleend, @@ -355,3 +403,18 @@ static void writechescape(char c, FILE *out) { } fputc(c, out); } + +static int inlinehtmlcase(char *data, char *start, char *end, FILE *out) { + int i; + int len; + char *endloc; + for (i = 0; start[i] != '\0'; ++i) + if (data[i] != start[i]) + return 0; + endloc = strstr(data, end); + if (endloc == NULL) + return 0; + len = endloc - data + strlen(end); + fwrite(data, 1, len, out); + return len; +} diff --git a/src/mdutil.c b/src/mdutil.c index e6ee579..e77bef7 100644 --- a/src/mdutil.c +++ b/src/mdutil.c @@ -127,7 +127,6 @@ notheader: if (line[0] == '<') { char *testline; - int isopen; testline = line + 1; for (i = 0; i < LEN(concretetags); ++i) { char *aftertag; @@ -140,12 +139,8 @@ notheader: return; } } - if (testline[0] == '/') { + if (testline[0] == '/') ++testline; - isopen = 0; - } - else - isopen = 1; for (i = 0; i < LEN(skeletontags); ++i) { char *aftertag; aftertag = after(skeletontags[i], testline); @@ -160,73 +155,15 @@ notheader: } } - /* < || `", newtestline[0]) - == NULL && - newtestline[0] != '\0') - ++newtestline; - if (newtestline[0] == '\0') - goto nothtml; - break; - /* Swallow unquoted attribute value */ - } - } - /* Swallow attribute value */ - - testline = newtestline; - } - - /* <[tag name][attribute]* || ') { + if (isgenerictag(line)) { ret->type = GENERICTAG; ret->data.isfirst = 1; return; } } -nothtml: ret->type = PLAIN; + ret->data.isfirst = 1; return; } @@ -246,6 +183,82 @@ char *realcontent(char *line, struct linedata *data) { return NULL; } +int isgenerictag(char *text) { + int isopen; + char *initialtext; + initialtext = text; + if (text[0] != '<') + return 0; + ++text; + if (text[0] == '/') { + ++text; + isopen = 0; + } + else + isopen = 1; + + /* < || `", newtext[0]) + == NULL && + newtext[0] != '\0') + ++newtext; + if (newtext[0] == '\0') + return 0; + break; + /* Swallow unquoted attribute value */ + } + } + /* Swallow attribute value */ + + text = newtext; + } + + /* <[tag name][attribute]* || ') + return text - initialtext + 1; + return 0; +} + static char *truncate(char *str) { while (isspace(str[0])) ++str;