Inline image support
This commit is contained in:
@@ -17,6 +17,11 @@ struct escape escapes[] = {
|
|||||||
|
|
||||||
static int writecodespan(char *data, int i, size_t len, FILE *out);
|
static int writecodespan(char *data, int i, size_t len, FILE *out);
|
||||||
static int writelink(char *data, int i, size_t len, FILE *out);
|
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 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 writeescaped(char *data, size_t len, FILE *out);
|
||||||
static void writechescape(char c, FILE *out);
|
static void writechescape(char c, FILE *out);
|
||||||
|
|
||||||
@@ -32,6 +37,8 @@ void writedata(char *data, size_t len, FILE *out) {
|
|||||||
goto special;
|
goto special;
|
||||||
if ((newi = writelink(data, i, len, out)) >= 0)
|
if ((newi = writelink(data, i, len, out)) >= 0)
|
||||||
goto special;
|
goto special;
|
||||||
|
if ((newi = writeimage(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);
|
||||||
@@ -76,6 +83,52 @@ static int writecodespan(char *data, int i, size_t len, FILE *out) {
|
|||||||
|
|
||||||
static int writelink(char *data, int i, size_t len, FILE *out) {
|
static int writelink(char *data, int i, size_t len, FILE *out) {
|
||||||
int textstart, textend, titlestart, titleend, linkstart, linkend;
|
int textstart, textend, titlestart, titleend, linkstart, linkend;
|
||||||
|
i = getlinkinfo(data, i, len, &textstart, &textend,
|
||||||
|
&titlestart, &titleend,
|
||||||
|
&linkstart, &linkend);
|
||||||
|
if (i < 0)
|
||||||
|
return -1;
|
||||||
|
fputs("<a href='", out);
|
||||||
|
writeescaped(data + linkstart, linkend - linkstart, out);
|
||||||
|
fputc('\'', out);
|
||||||
|
if (titlestart >= 0) {
|
||||||
|
fputs(" title='", out);
|
||||||
|
writeescaped(data + titlestart, titleend - titlestart, out);
|
||||||
|
fputc('\'', out);
|
||||||
|
}
|
||||||
|
fputc('>', out);
|
||||||
|
writeescaped(data + textstart, textend - textstart, out);
|
||||||
|
fputs("</a>", out);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int writeimage(char *data, int i, size_t len, FILE *out) {
|
||||||
|
int textstart, textend, titlestart, titleend, linkstart, linkend;
|
||||||
|
if (data[i++] != '!')
|
||||||
|
return -1;
|
||||||
|
i = getlinkinfo(data, i, len, &textstart, &textend,
|
||||||
|
&titlestart, &titleend,
|
||||||
|
&linkstart, &linkend);
|
||||||
|
if (i < 0)
|
||||||
|
return -1;
|
||||||
|
fputs("<img src='", out);
|
||||||
|
writeescaped(data + linkstart, linkend - linkstart, out);
|
||||||
|
fputc('\'', out);
|
||||||
|
if (titlestart >= 0) {
|
||||||
|
fputs(" title='", out);
|
||||||
|
writeescaped(data + titlestart, titleend - titlestart, out);
|
||||||
|
fputc('\'', out);
|
||||||
|
}
|
||||||
|
fputs(" alt='", out);
|
||||||
|
writeescaped(data + textstart, textend - textstart, out);
|
||||||
|
fputs("'>", out);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int getlinkinfo(char *data, int i, size_t len,
|
||||||
|
int *textstart, int *textend,
|
||||||
|
int *titlestart, int *titleend,
|
||||||
|
int *linkstart, int *linkend) {
|
||||||
int count;
|
int count;
|
||||||
enum {
|
enum {
|
||||||
INITIAL,
|
INITIAL,
|
||||||
@@ -99,7 +152,7 @@ static int writelink(char *data, int i, size_t len, FILE *out) {
|
|||||||
return -1;
|
return -1;
|
||||||
state = GETTEXT;
|
state = GETTEXT;
|
||||||
count = 1;
|
count = 1;
|
||||||
textstart = i + 1;
|
*textstart = i + 1;
|
||||||
break;
|
break;
|
||||||
case GETTEXT:
|
case GETTEXT:
|
||||||
if (data[i] == '[')
|
if (data[i] == '[')
|
||||||
@@ -107,8 +160,8 @@ static int writelink(char *data, int i, size_t len, FILE *out) {
|
|||||||
if (data[i] == ']')
|
if (data[i] == ']')
|
||||||
--count;
|
--count;
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
textend = i;
|
*textend = i;
|
||||||
linkstart = i;
|
*linkstart = i;
|
||||||
state = GETDESTSTART;
|
state = GETDESTSTART;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -120,11 +173,11 @@ static int writelink(char *data, int i, size_t len, FILE *out) {
|
|||||||
case GETDESTDETERMINE:
|
case GETDESTDETERMINE:
|
||||||
if (data[i] == '<') {
|
if (data[i] == '<') {
|
||||||
state = GETDESTPOINTY;
|
state = GETDESTPOINTY;
|
||||||
linkstart = i + 1;
|
*linkstart = i + 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
state = GETDESTNORMAL;
|
state = GETDESTNORMAL;
|
||||||
linkstart = i--;
|
*linkstart = i--;
|
||||||
count = 0;
|
count = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -132,7 +185,7 @@ static int writelink(char *data, int i, size_t len, FILE *out) {
|
|||||||
if (data[i] == '<' && data[i - 1] != '\\')
|
if (data[i] == '<' && data[i - 1] != '\\')
|
||||||
return -1;
|
return -1;
|
||||||
if (data[i] == '>' && data[i - 1] != '\\') {
|
if (data[i] == '>' && data[i - 1] != '\\') {
|
||||||
linkend = i;
|
*linkend = i;
|
||||||
state = GETTITLEDETERMINE;
|
state = GETTITLEDETERMINE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -143,53 +196,53 @@ static int writelink(char *data, int i, size_t len, FILE *out) {
|
|||||||
--count;
|
--count;
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
state = GETTITLEDETERMINE;
|
state = GETTITLEDETERMINE;
|
||||||
linkend = i--;
|
*linkend = i--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (count != 0)
|
if (count != 0)
|
||||||
break;
|
break;
|
||||||
if (isctrl(data[i]) || data[i] == ' ') {
|
if (isctrl(data[i]) || data[i] == ' ') {
|
||||||
state = GETTITLEDETERMINE;
|
state = GETTITLEDETERMINE;
|
||||||
linkend = i;
|
*linkend = i;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GETTITLEDETERMINE:
|
case GETTITLEDETERMINE:
|
||||||
switch (data[i]) {
|
switch (data[i]) {
|
||||||
case '"':
|
case '"':
|
||||||
state = GETTITLEDOUBLEQUOTE;
|
state = GETTITLEDOUBLEQUOTE;
|
||||||
titlestart = i + 1;
|
*titlestart = i + 1;
|
||||||
break;
|
break;
|
||||||
case '\'':
|
case '\'':
|
||||||
state = GETTITLESINGLEQUOTE;
|
state = GETTITLESINGLEQUOTE;
|
||||||
titlestart = i + 1;
|
*titlestart = i + 1;
|
||||||
break;
|
break;
|
||||||
case '(':
|
case '(':
|
||||||
state = GETTITLEPAREN;
|
state = GETTITLEPAREN;
|
||||||
count = 1;
|
count = 1;
|
||||||
titlestart = i + 1;
|
*titlestart = i + 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
--i;
|
--i;
|
||||||
titlestart = titleend = -1;
|
*titlestart = *titleend = -1;
|
||||||
state = NEARLYTHERE;
|
state = NEARLYTHERE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GETTITLEDOUBLEQUOTE:
|
case GETTITLEDOUBLEQUOTE:
|
||||||
if (data[i] == '"' && data[i - 1] != '\\') {
|
if (data[i] == '"' && data[i - 1] != '\\') {
|
||||||
titleend = i;
|
*titleend = i;
|
||||||
state = NEARLYTHERE;
|
state = NEARLYTHERE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GETTITLESINGLEQUOTE:
|
case GETTITLESINGLEQUOTE:
|
||||||
if (data[i] == '\'' && data[i - 1] != '\\') {
|
if (data[i] == '\'' && data[i - 1] != '\\') {
|
||||||
titleend = i;
|
*titleend = i;
|
||||||
state = NEARLYTHERE;
|
state = NEARLYTHERE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GETTITLEPAREN:
|
case GETTITLEPAREN:
|
||||||
if (data[i] == '(' || data[i] == ')') {
|
if (data[i] == '(' || data[i] == ')') {
|
||||||
if (data[i - 1] != '\\') {
|
if (data[i - 1] != '\\') {
|
||||||
titleend = i;
|
*titleend = i;
|
||||||
state = NEARLYTHERE;
|
state = NEARLYTHERE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -206,18 +259,6 @@ static int writelink(char *data, int i, size_t len, FILE *out) {
|
|||||||
done:
|
done:
|
||||||
if (state != DONE)
|
if (state != DONE)
|
||||||
return -1;
|
return -1;
|
||||||
fputs("<a", out);
|
|
||||||
fputs(" href='", out);
|
|
||||||
writeescaped(data + linkstart, linkend - linkstart, out);
|
|
||||||
fputc('\'', out);
|
|
||||||
if (titlestart >= 0) {
|
|
||||||
fputs(" title='", out);
|
|
||||||
writeescaped(data + titlestart, titleend - titlestart, out);
|
|
||||||
fputc('\'', out);
|
|
||||||
}
|
|
||||||
fputc('>', out);
|
|
||||||
writeescaped(data + textstart, textend - textstart, out);
|
|
||||||
fputs("</a>", out);
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user