#include #include #include int find_break_point (object string, int n) { const char *s = string->st.st_self; int i; for (i = 0; i < string->st.st_fillp; ++i) { if (n == 0) { for (; (i > 0) && !isspace (s[i]); --i); return ((i << 1) | 1); } else if (!isspace (s[i])) --n; } return (n << 1); } #define PREFORMATTEDP 1 #define ADD_PARAGRAPHS_P 2 #define LINKIFY_URLS_P 4 #define IN_PARA_P 8 #define IGNORE_LEADING_WHITESPACE_P 16 #define IGNORE_TRAILING_WHITESPACE_P 32 object format_text (object string, object stream, int flags, int length) { const char *s = string->st.st_self; int i = 0, j; object in_para_p = (flags & IN_PARA_P) ? Ct : Cnil; int url_state = 0, url_start = 0, url_end = 0; if (flags & IGNORE_LEADING_WHITESPACE_P) for (; (i < length) && isspace (s[i]); ++i); for (; /* test further down */; ++i) { if (url_state && (i == url_end)) { if (url_state == 2) writestr_stream ("", stream); else writestr_stream ("\">", stream); if (url_state == 1) { url_state = 2; i = url_start; } else url_state = 0; } if ((i < length) && isspace (s[i]) && !(flags & PREFORMATTEDP)) { int nl_count = 0; int processp; for (; (i < length) && isspace (s[i]); ++i) { if (s[i] == '\n') ++nl_count; } processp = (i < length) || !(flags & IGNORE_TRAILING_WHITESPACE_P); if (nl_count && (flags & ADD_PARAGRAPHS_P)) { if (nl_count >= 2) { if (in_para_p != Cnil) { writestr_stream ("

", stream); in_para_p = Cnil; } if (processp) { writestr_stream ("

", stream); in_para_p = Ct; } } else if (processp) writestr_stream ("
", stream); } else if (processp) writec_stream (' ', stream); } if (i >= length) break; switch (s[i]) { case '<': writestr_stream ("<", stream); break; case '>': writestr_stream (">", stream); break; case '&': if ((i + 2) < length) { for (j = i + ((s[i + 1] == '#') ? 2 : 1); (j < length) && isalnum (s[j]); ++j); if ((j < length) && (s[j] == ';')) { writec_stream ('&', stream); break; } } writestr_stream ("&", stream); break; case 'h': case 'f': if ((flags & LINKIFY_URLS_P) && !url_state && ((i + 10) < length) && (s[i + 5] == '/') && ((strncmp (s + i, "http://", 7) == 0) || (strncmp (s + i, "ftp://", 6) == 0))) { for (j = i + 6; ((j < length) && !isspace (s[j]) && (s[j] != '"') && (s[j] != '\'') && (s[j] != '<') && (s[j] != '>') && (s[j] != '[') && (s[j] != ']') && (s[j] != '(') && (s[j] != ')') && (s[j] != '{') && (s[j] != '}') && !((s[j] == '&') && (strncmp (s + j + 1, "nbsp;", 5) == 0))); ++j); /* Ensure that the last character is a slash or alphanumeric. */ for (; (s[j - 1] != '/') && !isalnum (s[j - 1]); --j); /* Only a URL if it satisfies the minimum length. */ if ((j - i) > 10) { url_start = i; url_end = j; url_state = (((strncmp (s + j - 4, ".gif", 4) == 0) || (strncmp (s + j - 4, ".jpg", 4) == 0) || (strncmp (s + j - 5, ".jpeg", 5) == 0) || (strncmp (s + j - 4, ".png", 4) == 0)) ? 3 : 1); writestr_stream ((url_state == 1) ? "st.st_self; int length = string->st.st_fillp, i = 0, j; int width = max_width; while (i < length) { if (isspace (s[i])) { writec_stream (s[i], stream); if (s[i] == '\n') width = max_width; else --width; ++i; } else { for (j = i; (j < length) && !isspace (s[j]); ++j); width -= (j - i); if (width < 0) { writec_stream ('\n', stream); width = max_width - (j - i); } for (; i < j; ++i) writec_stream (s[i], stream); if (width < 0) { writec_stream ('\n', stream); width = max_width; } } } }