Inline html
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <util.h>
|
||||
#include <mdutil.h>
|
||||
#include <inlines.h>
|
||||
|
||||
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, "<!--", 4) == 0) {
|
||||
char *end, *text;
|
||||
int j;
|
||||
text = data + 4;
|
||||
end = strstr(text, "-->");
|
||||
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, "<![CDATA[", "]]>", 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;
|
||||
}
|
||||
|
||||
145
src/mdutil.c
145
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:
|
||||
}
|
||||
}
|
||||
|
||||
/* < || </ */
|
||||
|
||||
if (!isalpha(testline[0]))
|
||||
goto nothtml;
|
||||
++testline;
|
||||
while (isalnum(testline[0]) || testline[0] == '-')
|
||||
++testline;
|
||||
|
||||
/* <[tag name] || </[tag name] */
|
||||
|
||||
for (;;) {
|
||||
char *newtestline;
|
||||
newtestline = truncate(testline);
|
||||
|
||||
if (!isalpha(newtestline[0]) &&
|
||||
strchr("_:", newtestline[0]) == NULL)
|
||||
break;
|
||||
++newtestline;
|
||||
while (isalnum(newtestline[0]) ||
|
||||
strchr("_.:-", newtestline[0]) != NULL)
|
||||
++newtestline;
|
||||
/* Swallow attribute name */
|
||||
|
||||
newtestline = truncate(newtestline);
|
||||
if (newtestline[0] == '=') {
|
||||
char start;
|
||||
++newtestline;
|
||||
newtestline = truncate(newtestline);
|
||||
start = newtestline[0];
|
||||
switch (start) {
|
||||
case '\'': case '"':
|
||||
while (newtestline[0] != start &&
|
||||
newtestline[0] != '\0')
|
||||
++newtestline;
|
||||
if (newtestline[0] == '\0')
|
||||
goto nothtml;
|
||||
break;
|
||||
/* Swallow single/double quoted attribute
|
||||
* value */
|
||||
default:
|
||||
while (strchr("\"'=<>`", 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]* || </tag name][attribute]* */
|
||||
if (isopen && testline[0] == '/')
|
||||
++testline;
|
||||
if (testline[0] == '>') {
|
||||
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;
|
||||
|
||||
/* < || </ */
|
||||
|
||||
if (!isalpha(text[0]))
|
||||
return 0;
|
||||
while (isalnum(text[0]) || text[0] == '-')
|
||||
++text;
|
||||
|
||||
/* <[tag name] || </[tag name] */
|
||||
|
||||
for (;;) {
|
||||
char *newtext;
|
||||
newtext = truncate(text);
|
||||
|
||||
if (!isalpha(newtext[0]) &&
|
||||
strchr("_:", newtext[0]) == NULL)
|
||||
break;
|
||||
++newtext;
|
||||
while (isalnum(newtext[0]) ||
|
||||
strchr("_.:-", newtext[0]) != NULL)
|
||||
++newtext;
|
||||
/* Swallow attribute name */
|
||||
|
||||
newtext = truncate(newtext);
|
||||
if (newtext[0] == '=') {
|
||||
char start;
|
||||
++newtext;
|
||||
newtext = truncate(newtext);
|
||||
start = newtext[0];
|
||||
switch (start) {
|
||||
case '\'': case '"':
|
||||
while (newtext[0] != start &&
|
||||
newtext[0] != '\0')
|
||||
++newtext;
|
||||
if (newtext[0] == '\0')
|
||||
return 0;
|
||||
break;
|
||||
/* Swallow single/double quoted attribute
|
||||
* value */
|
||||
default:
|
||||
while (strchr("\"'=<>`", 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]* || </tag name][attribute]* */
|
||||
if (isopen && text[0] == '/')
|
||||
++text;
|
||||
if (text[0] == '>')
|
||||
return text - initialtext + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *truncate(char *str) {
|
||||
while (isspace(str[0]))
|
||||
++str;
|
||||
|
||||
Reference in New Issue
Block a user