Пример #1
0
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;
}
Пример #2
0
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, &current->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;
}