Inline html
This commit is contained in:
@@ -54,5 +54,7 @@ struct linedata {
|
|||||||
void identifyline(char *line, struct linedata *prev, struct linedata *ret);
|
void identifyline(char *line, struct linedata *prev, struct linedata *ret);
|
||||||
/* prev is almost never used, but sometimes it is. */
|
/* prev is almost never used, but sometimes it is. */
|
||||||
char *realcontent(char *line, struct linedata *data);
|
char *realcontent(char *line, struct linedata *data);
|
||||||
|
int isgenerictag(char *text);
|
||||||
|
/* Identifies open and close tags */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
|
#include <mdutil.h>
|
||||||
#include <inlines.h>
|
#include <inlines.h>
|
||||||
|
|
||||||
static const char *punctuation = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
|
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 writeimage(char *data, int i, size_t len, FILE *out);
|
||||||
static int writeautolink(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 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,
|
static int getlinkinfo(char *data, int i, size_t len,
|
||||||
int *textstart, int *textend,
|
int *textstart, int *textend,
|
||||||
int *titlestart, int *titleend,
|
int *titlestart, int *titleend,
|
||||||
int *linkstart, int *linkend);
|
int *linkstart, int *linkend);
|
||||||
static void writeescaped(char *data, size_t len, FILE *out);
|
static void writeescaped(char *data, size_t len, FILE *out);
|
||||||
static void writechescape(char c, 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) {
|
void writeline(char *data, FILE *out) {
|
||||||
writedata(data, strlen(data), out);
|
writedata(data, strlen(data), out);
|
||||||
@@ -63,6 +67,8 @@ void writedata(char *data, size_t len, FILE *out) {
|
|||||||
goto special;
|
goto special;
|
||||||
if ((newi = writehardbreak(data, i, len, out)) >= 0)
|
if ((newi = writehardbreak(data, i, len, out)) >= 0)
|
||||||
goto special;
|
goto special;
|
||||||
|
if ((newi = writerawhtml(data, i, len, out)) >= 0)
|
||||||
|
goto special;
|
||||||
if (data[i] == '\\') {
|
if (data[i] == '\\') {
|
||||||
if (strchr(punctuation, data[i + 1]) == NULL)
|
if (strchr(punctuation, data[i + 1]) == NULL)
|
||||||
writechescape('\\', out);
|
writechescape('\\', out);
|
||||||
@@ -202,6 +208,48 @@ static int writehardbreak(char *data, int i, size_t len, FILE *out) {
|
|||||||
return i + codelen;
|
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,
|
static int getlinkinfo(char *data, int i, size_t len,
|
||||||
int *textstart, int *textend,
|
int *textstart, int *textend,
|
||||||
int *titlestart, int *titleend,
|
int *titlestart, int *titleend,
|
||||||
@@ -355,3 +403,18 @@ static void writechescape(char c, FILE *out) {
|
|||||||
}
|
}
|
||||||
fputc(c, 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] == '<') {
|
if (line[0] == '<') {
|
||||||
char *testline;
|
char *testline;
|
||||||
int isopen;
|
|
||||||
testline = line + 1;
|
testline = line + 1;
|
||||||
for (i = 0; i < LEN(concretetags); ++i) {
|
for (i = 0; i < LEN(concretetags); ++i) {
|
||||||
char *aftertag;
|
char *aftertag;
|
||||||
@@ -140,12 +139,8 @@ notheader:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (testline[0] == '/') {
|
if (testline[0] == '/')
|
||||||
++testline;
|
++testline;
|
||||||
isopen = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
isopen = 1;
|
|
||||||
for (i = 0; i < LEN(skeletontags); ++i) {
|
for (i = 0; i < LEN(skeletontags); ++i) {
|
||||||
char *aftertag;
|
char *aftertag;
|
||||||
aftertag = after(skeletontags[i], testline);
|
aftertag = after(skeletontags[i], testline);
|
||||||
@@ -160,73 +155,15 @@ notheader:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* < || </ */
|
if (isgenerictag(line)) {
|
||||||
|
|
||||||
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] == '>') {
|
|
||||||
ret->type = GENERICTAG;
|
ret->type = GENERICTAG;
|
||||||
ret->data.isfirst = 1;
|
ret->data.isfirst = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nothtml:
|
|
||||||
|
|
||||||
ret->type = PLAIN;
|
ret->type = PLAIN;
|
||||||
|
ret->data.isfirst = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -246,6 +183,82 @@ char *realcontent(char *line, struct linedata *data) {
|
|||||||
return NULL;
|
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) {
|
static char *truncate(char *str) {
|
||||||
while (isspace(str[0]))
|
while (isspace(str[0]))
|
||||||
++str;
|
++str;
|
||||||
|
|||||||
Reference in New Issue
Block a user