/*
* inline.c:
* In-line markup.
*
* - URLs are turned into links
*
* - ___ text ___ URL is turned into a link with the given text
*
* - ||| URL alt-text ||| is turned into an
tag with the given
* alt-text
*
* - *** strong ***
*
* - /// emphasis ///
*
* - ### cite ###
*
* - <>&" are turned into the appropriate HTML escapes.
*
* - \\\ is turned into
*
* Copyright (c) 2003 Chris Lightfoot. All rights reserved.
* Email: chris@ex-parrot.com; WWW: http://www.ex-parrot.com/~chris/
*
*/
static const char rcsid[] = "$Id: inline.c,v 1.3 2003/06/01 11:39:44 chris Exp $";
#include
#include
#include
#include "htmlise.h"
static void inline_markup_words(FILE *fp, char **words, const size_t nwords) {
size_t i;
int in_strong = 0, in_em = 0, in_cite = 0;
/* Go through words applying markup. XXX may generate overlapping tags. */
for (i = 0; i < nwords; ++i) {
size_t j;
if (!*words[i])
continue;
if (strcmp(words[i], "\\\\\\") == 0)
fprintf(fp, "
");
else if (strcmp(words[i], "***") == 0) {
if (in_strong)
fprintf(fp, "");
else
fprintf(fp, "");
in_strong = !in_strong;
} else if (strcmp(words[i], "///") == 0) {
if (in_em)
fprintf(fp, "");
else
fprintf(fp, "");
in_em = !in_em;
} else if (strcmp(words[i], "###") == 0) {
if (in_cite)
fprintf(fp, "");
else
fprintf(fp, "");
in_cite = !in_cite;
} else if (strcmp(words[i], "|||") == 0) {
/* Image. Can't have markup inside the alt text. */
for (j = i + 1; j < nwords && strcmp(words[j], "|||") != 0; ++j);
if (j < nwords) {
fprintf(fp, "
");
}
} else if (strncmp(words[i], "http://", 7) == 0 || strncmp(words[i], "ftp://", 6) == 0)
fprintf(fp, "%s", words[i], words[i]);
else if (strcmp(words[i], "___") == 0) {
/* Link. */
for (j = i + 2; j < nwords - 1 && strcmp(words[j], "___") != 0; ++j);
if (j < nwords - 1) {
int lastc = 0;
size_t l;
fprintf(fp, "", words[j + 1]);
l = strlen(words[j - 1]) - 1;
if (strchr("\"`'.,;:()[]?!", words[j - 1][l])) {
lastc = words[j - 1][l];
words[j - 1][l] = 0;
}
/*
while (i < j) {
size_t l;
if (i == j - 1 && strchr("\"`'.,;:()[]", words[i][l = strlen(words[i]) - 1])) {
lastc = words[i][l];
words[i][l] = 0;
}
fprintf(fp, "%s%s", words[i++], i < j ? " " : "");
}
++i;
*/
inline_markup_words(fp, words + i + 1, j - i - 1);
fprintf(fp, "");
if (lastc)
putc(lastc, fp);
i = j + 1;
}
} else
fprintf(fp, "%s", words[i]);
if (i < nwords - 1)
putc(' ', fp);
}
}
/* emit_as_html STREAM PARAGRAPH
* Emit PARAGRAPH to STREAM, converting its text to HTML. */
void emit_as_html(FILE *fp, const struct paragraph *P) {
static char *buf, **words;
static size_t buflen, nwordsalloc;
size_t i, n, nwords = 0;
const char *p;
char *q, *ws, *we;
for (i = 0, n = 0; i < P->nlines; ++i)
n += strlen(P->lines[i]) + 1;
/* Conservative; " (1) -> " (5). */
if (!buf || n * 6 + 1 > buflen)
buf = realloc(buf, buflen = n * 5 + 1);
for (i = 0, q = buf; i < P->nlines; ++i) {
for (p = P->lines[i]; *p; ++p) {
if (*p == '&') {
strcpy(q, "&");
q += 5;
} else if (*p == '<') {
strcpy(q, "<");
q += 4;
} else if (*p == '>') {
strcpy(q, ">");
q += 4;
} else if (*p == '\"') {
strcpy(q, """);
q += 6;
} else
*q++ = *p;
}
*q++ = '\n';
}
*q = 0;
/* Break into words. */
if (!words)
words = malloc((nwordsalloc = 100) * sizeof *words);
ws = buf;
while (1) {
while (*ws && strchr(" \n", *ws)) ++ws;
if (!*ws) break;
/* End of this word. */
we = ws + strcspn(ws, " \n");
words[nwords++] = ws;
if (*we) {
*we = 0;
ws = we + 1;
} else
break;
if (nwords == nwordsalloc)
words = realloc(words, (nwordsalloc *= 2) * sizeof *words);
}
inline_markup_words(fp, words, nwords);
}