/* * 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); }