static void smartquotes_insert_cb(GtkTextBuffer *buffer, GtkTextIter *iter, gchar *text, gint len, gpointer user_data) { int i; for (i = 0; i < len; i++) { if (count_quotes(text[i])) { smartquotes_begin(buffer); break; } } }
static void smartquotes_delete_cb(GtkTextBuffer *buffer, GtkTextIter *i1, GtkTextIter *i2) { gunichar c; GtkTextIter i = *i1; while (gtk_text_iter_in_range(&i, i1, i2)) { c = gtk_text_iter_get_char(&i); if (count_quotes(c)) { smartquotes_begin(buffer); break; } gtk_text_iter_forward_char(&i); } }
/** Write a string to the output, quoting and escaping as necessary. This routine optimizes its use of quotes by counting the number of quotes in the string and using the quotes that occur least in the string itself. */ static void write_string(FILE *file, const char *value) { const char *quote; char quote_char = '"'; int single_count, double_count; double_count = count_quotes(value, '"'); if (double_count != 0) { single_count = count_quotes(value, '\''); if (single_count < double_count) { quote_char = '\''; } } fputc(quote_char, file); while ((quote = strchr(value, quote_char)) != NULL) { fwrite(value, 1, quote - value, file); fputc(quote_char, file); fputc(quote_char, file); value = quote + 1; } fwrite(value, 1, strlen(value), file); fputc(quote_char, file); }
static void standard_quotes_command(client * c) { char * authorname; char * authorend; char buffer[128]; authorname = strstr(c->buffer, " \""); if (authorname) { authorname += 2; authorend = strstr(authorname, "\"\r\n"); if (authorend) { author * a = find_author(authors, authorname, authorend - authorname); if (a) { sprintf(buffer, "%d\r\n", count_quotes(a->quotes)); } else { strcpy(buffer, "No such author: "); strncat(buffer, authorname, authorend - authorname); strcat(buffer, "\r\n"); } send(c->socket, buffer, strlen(buffer), 0); } } c->buffer_content = 0; }
static void run_smartquotes(GtkTextBuffer *buffer) { GtkTextIter pos, nextpos; gunichar lastc = 0, c = 0, nextc; int balance[10] = {0}; /* max 10 levels of nesting. */ int curnesting = -1; gboolean insidetag = FALSE, closing; int quotes; /* this runs as the user is typing, so undo doesn't make much sense. gtk_text_buffer_begin_user_action(buffer); */ gtk_text_buffer_get_start_iter(buffer, &pos); while ((c = gtk_text_iter_get_char(&pos)) != 0) { nextpos = pos; gtk_text_iter_forward_char(&nextpos); nextc = gtk_text_iter_get_char(&nextpos); /*g_printf("ofs %d\n", gtk_text_iter_get_offset(&pos));*/ if (c == '<') insidetag = TRUE; else if (c == '>') insidetag = FALSE; quotes = count_quotes(c); if (insidetag || quotes == 0) { lastc = c; gtk_text_iter_forward_char(&pos); continue; } closing = (curnesting >= 0 && balance[curnesting] == quotes); if (quotes == 1 && g_unichar_isalnum(lastc) && (!closing || g_unichar_isalnum(nextc))) { /* an apostrophe. fix it up, but don't change nesting. */ /*g_print("n %d apos %c\n", curnesting, (char)c);*/ buffer_change_quote(buffer, &pos, &nextpos, c, UNICODE_RIGHTSINGLEQUOTE); } else if (closing) { /*g_print("n %d right %c\n", curnesting, (char)c);*/ buffer_change_quote(buffer, &pos, &nextpos, c, quotes == 1 ? UNICODE_RIGHTSINGLEQUOTE : UNICODE_RIGHTDOUBLEQUOTE); curnesting--; } else { /*g_print("n %d left %c\n", curnesting, (char)c);*/ buffer_change_quote(buffer, &pos, &nextpos, c, quotes == 1 ? UNICODE_LEFTSINGLEQUOTE : UNICODE_LEFTDOUBLEQUOTE); curnesting++; balance[curnesting] = quotes; } if (curnesting >= 9) { g_warning("too many nested quotes."); } lastc = c; gtk_text_iter_forward_char(&pos); } /* gtk_text_buffer_end_user_action(buffer); */ }