int msg_get_plain_text(int age, char *buffer, int max) { int ct = 0, i; doc_token_t token; msg_ptr msg = msg_get(age); cptr pos = string_buffer(msg->msg); bool done = FALSE; while (!done) { pos = doc_lex(pos, &token); if (token.type == DOC_TOKEN_EOF) break; if (token.type == DOC_TOKEN_TAG) continue; /* assume only color tags */ for (i = 0; i < token.size; i++) { if (ct >= max - 4) { buffer[ct++] = '.'; buffer[ct++] = '.'; buffer[ct++] = '.'; done = TRUE; break; } buffer[ct++] = token.pos[i]; } } buffer[ct] = '\0'; return ct; }
doc_pos_t doc_insert(doc_ptr doc, cptr text) { doc_token_t token; doc_token_t queue[10]; int qidx = 0; cptr pos = text; int i, j, cb; doc_style_ptr style = NULL; for (;;) { pos = doc_lex(pos, &token); if (token.type == DOC_TOKEN_EOF) break; assert(pos != token.pos); if (token.type == DOC_TOKEN_TAG) { _doc_process_tag(doc, &token.tag); continue; } if (token.type == DOC_TOKEN_NEWLINE) { doc_newline(doc); continue; } if (token.type == DOC_TOKEN_WHITESPACE) { doc_insert_space(doc, token.size); continue; } assert(token.type == DOC_TOKEN_WORD); assert(token.size > 0); /* Queue Complexity is for "<color:R>difficult</color>!" which is actually a bit common! */ qidx = 0; cb = token.size; queue[qidx++] = token; while (qidx < 10) { cptr peek = doc_lex(pos, &token); if (token.type == DOC_TOKEN_WORD) { cb += token.size; } else if ( token.type == DOC_TOKEN_TAG && (token.tag.type == DOC_TAG_COLOR || token.tag.type == DOC_TAG_CLOSE_COLOR) ) { } else { break; } queue[qidx++] = token; pos = peek; } style = doc_current_style(doc); /* be careful ... this changes on <color:_> tags! */ if ( doc->cursor.x + cb >= style->right && !(style->options & DOC_STYLE_NO_WORDWRAP) ) { doc_newline(doc); if (style->indent) doc_insert_space(doc, style->indent); } for (i = 0; i < qidx; i++) { doc_token_ptr current = &queue[i]; if (current->type == DOC_TOKEN_TAG) { assert(current->tag.type == DOC_TAG_COLOR || current->tag.type == DOC_TAG_CLOSE_COLOR); _doc_process_tag(doc, ¤t->tag); style = doc_current_style(doc); } else if (doc->cursor.x < style->right) { doc_char_ptr cell = doc_char(doc, doc->cursor); assert(current->type == DOC_TOKEN_WORD); assert(cell); for (j = 0; j < current->size; j++) { cell->a = style->color; cell->c = current->pos[j]; if (cell->c == '\t') cell->c = ' '; if (doc->cursor.x == style->right - 1) { if (style->options & DOC_STYLE_NO_WORDWRAP) break; doc_newline(doc); if (style->indent) doc_insert_space(doc, style->indent); cell = doc_char(doc, doc->cursor); } else { doc->cursor.x++; cell++; } } } } } assert(0 <= doc->cursor.x && doc->cursor.x < doc->width); return doc->cursor; }