From 4e70c61ae5fc9d600f2bb05e53088f3360bc379d Mon Sep 17 00:00:00 2001 From: Nate Choe Date: Sun, 1 May 2022 04:03:18 -0500 Subject: [PATCH] Inline image support --- src/inlines.c | 95 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 27 deletions(-) diff --git a/src/inlines.c b/src/inlines.c index 92e1886..6d178d2 100644 --- a/src/inlines.c +++ b/src/inlines.c @@ -17,6 +17,11 @@ struct escape escapes[] = { 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 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 writechescape(char c, FILE *out); @@ -32,6 +37,8 @@ void writedata(char *data, size_t len, FILE *out) { goto special; if ((newi = writelink(data, i, len, out)) >= 0) goto special; + if ((newi = writeimage(data, i, len, out)) >= 0) + goto special; if (data[i] == '\\') { if (strchr(punctuation, data[i + 1]) == NULL) 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) { int textstart, textend, titlestart, titleend, linkstart, linkend; + i = getlinkinfo(data, i, len, &textstart, &textend, + &titlestart, &titleend, + &linkstart, &linkend); + if (i < 0) + return -1; + fputs("= 0) { + fputs(" title='", out); + writeescaped(data + titlestart, titleend - titlestart, out); + fputc('\'', out); + } + fputc('>', out); + writeescaped(data + textstart, textend - textstart, out); + fputs("", 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("= 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; enum { INITIAL, @@ -99,7 +152,7 @@ static int writelink(char *data, int i, size_t len, FILE *out) { return -1; state = GETTEXT; count = 1; - textstart = i + 1; + *textstart = i + 1; break; case GETTEXT: if (data[i] == '[') @@ -107,8 +160,8 @@ static int writelink(char *data, int i, size_t len, FILE *out) { if (data[i] == ']') --count; if (count == 0) { - textend = i; - linkstart = i; + *textend = i; + *linkstart = i; state = GETDESTSTART; } break; @@ -120,11 +173,11 @@ static int writelink(char *data, int i, size_t len, FILE *out) { case GETDESTDETERMINE: if (data[i] == '<') { state = GETDESTPOINTY; - linkstart = i + 1; + *linkstart = i + 1; } else { state = GETDESTNORMAL; - linkstart = i--; + *linkstart = i--; count = 0; } break; @@ -132,7 +185,7 @@ static int writelink(char *data, int i, size_t len, FILE *out) { if (data[i] == '<' && data[i - 1] != '\\') return -1; if (data[i] == '>' && data[i - 1] != '\\') { - linkend = i; + *linkend = i; state = GETTITLEDETERMINE; } break; @@ -143,53 +196,53 @@ static int writelink(char *data, int i, size_t len, FILE *out) { --count; if (count < 0) { state = GETTITLEDETERMINE; - linkend = i--; + *linkend = i--; break; } if (count != 0) break; if (isctrl(data[i]) || data[i] == ' ') { state = GETTITLEDETERMINE; - linkend = i; + *linkend = i; } break; case GETTITLEDETERMINE: switch (data[i]) { case '"': state = GETTITLEDOUBLEQUOTE; - titlestart = i + 1; + *titlestart = i + 1; break; case '\'': state = GETTITLESINGLEQUOTE; - titlestart = i + 1; + *titlestart = i + 1; break; case '(': state = GETTITLEPAREN; count = 1; - titlestart = i + 1; + *titlestart = i + 1; break; default: --i; - titlestart = titleend = -1; + *titlestart = *titleend = -1; state = NEARLYTHERE; } break; case GETTITLEDOUBLEQUOTE: if (data[i] == '"' && data[i - 1] != '\\') { - titleend = i; + *titleend = i; state = NEARLYTHERE; } break; case GETTITLESINGLEQUOTE: if (data[i] == '\'' && data[i - 1] != '\\') { - titleend = i; + *titleend = i; state = NEARLYTHERE; } break; case GETTITLEPAREN: if (data[i] == '(' || data[i] == ')') { if (data[i - 1] != '\\') { - titleend = i; + *titleend = i; state = NEARLYTHERE; } } @@ -206,18 +259,6 @@ static int writelink(char *data, int i, size_t len, FILE *out) { done: if (state != DONE) return -1; - fputs("= 0) { - fputs(" title='", out); - writeescaped(data + titlestart, titleend - titlestart, out); - fputc('\'', out); - } - fputc('>', out); - writeescaped(data + textstart, textend - textstart, out); - fputs("", out); return i; }