示例#1
0
int doc_display_help_aux(cptr file_name, cptr topic, rect_t display)
{
    int     rc = _OK;
    FILE   *fp = NULL;
    char    path[1024];
    char    caption[1024];
    doc_ptr doc = NULL;
    int     top = 0;

    /* Check for file_name#topic from a lazy client */
    if (!topic)
    {
        cptr pos = strchr(file_name, '#');
        if (pos)
        {
            string_ptr name = string_copy_sn(file_name, pos - file_name);
            int        result = doc_display_help_aux(string_buffer(name), pos + 1, display);

            string_free(name);
            return result;
        }
    }

    sprintf(caption, "Help file '%s'", file_name);
    path_build(path, sizeof(path), ANGBAND_DIR_HELP, file_name);
    fp = my_fopen(path, "r");
    if (!fp)
    {
        cmsg_format(TERM_VIOLET, "Cannot open '%s'.", file_name);
        msg_print(NULL);
        return _OK;
    }

    doc = doc_alloc(MIN(80, display.cx));
    doc_read_file(doc, fp);
    my_fclose(fp);

    if (topic)
    {
        doc_pos_t pos = doc_find_bookmark(doc, topic);
        if (doc_pos_is_valid(pos))
            top = pos.y;
    }

    rc = doc_display_aux(doc, caption, top, display);
    doc_free(doc);
    return rc;
}
示例#2
0
vec_ptr string_split(string_ptr str, char sep)
{
    vec_ptr     v = vec_alloc((vec_free_f)string_free);
    const char *pos = str->buf;
    int         done = 0;

    while (!done && *pos)
    {
        const char *next = strchr(pos, sep);
        string_ptr  s;

        if (!next && *pos)
        {
            next = strchr(pos, '\0');
            assert(next);
            done = 1;
        }

        s = string_copy_sn(pos, next - pos);
        vec_add(v, s);
        pos = next + 1;
    }
    return v;
}
示例#3
0
string_ptr string_copy_s(const char *val)
{
    if (!val)
        val = "";
    return string_copy_sn(val, strlen(val));
}
示例#4
0
string_ptr string_copy(string_ptr str)
{
    return string_copy_sn(str->buf, str->len);
}
示例#5
0
string_ptr substring_copy(substring_ptr ss)
{
    return string_copy_sn(substring_buffer(ss), ss->len);
}
示例#6
0
string_ptr string_alloc(void)
{
    return string_copy_sn("", 0);
}
示例#7
0
static void _doc_process_tag(doc_ptr doc, doc_tag_ptr tag)
{
    if ( tag->type == DOC_TAG_CLOSE_COLOR
      || tag->type == DOC_TAG_CLOSE_STYLE
      || tag->type == DOC_TAG_CLOSE_INDENT )
    {
        doc_pop_style(doc);
    }
    else if (tag->type == DOC_TAG_COLOR)
    {
        assert(tag->arg);
        if (tag->arg_size == 1)
        {
            if (tag->arg[0] == '*')
                doc_pop_style(doc);
            else
            {
                doc_style_t style = *doc_current_style(doc); /* copy */
                switch (tag->arg[0])
                {
                case 'd': style.color = TERM_DARK; break;
                case 'w': style.color = TERM_WHITE; break;
                case 's': style.color = TERM_SLATE; break;
                case 'o': style.color = TERM_ORANGE; break;
                case 'r': style.color = TERM_RED; break;
                case 'g': style.color = TERM_GREEN; break;
                case 'b': style.color = TERM_BLUE; break;
                case 'u': style.color = TERM_UMBER; break;
                case 'D': style.color = TERM_L_DARK; break;
                case 'W': style.color = TERM_L_WHITE; break;
                case 'v': style.color = TERM_VIOLET; break;
                case 'y': style.color = TERM_YELLOW; break;
                case 'R': style.color = TERM_L_RED; break;
                case 'G': style.color = TERM_L_GREEN; break;
                case 'B': style.color = TERM_L_BLUE; break;
                case 'U': style.color = TERM_L_UMBER; break;
                }
                doc_push_style(doc, &style);
            }
        }
        else
        {
            string_ptr  arg = string_copy_sn(tag->arg, tag->arg_size);
            doc_style_t style = *doc_current_style(doc); /* copy */
            doc_style_f f = _get_doc_style_f(doc, string_buffer(arg));

            if (f)
                f(&style);

            {/* We don't copy the named style, just its color. */
             /* Also, we damn well better push a style or we'll be upset
                when the good little user pops! */
                doc_style_t copy = *doc_current_style(doc);
                copy.color = style.color;
                doc_push_style(doc, &copy);
            }
            string_free(arg);
        }
    }
    else if (tag->type == DOC_TAG_INDENT)
    {
        doc_style_t style = *doc_current_style(doc);
        style.left = doc->cursor.x;
        doc_push_style(doc, &style);
    }
    else
    {
        string_ptr arg = string_copy_sn(tag->arg, tag->arg_size);

        switch (tag->type)
        {
        case DOC_TAG_STYLE:
            if (tag->arg_size == 1 && tag->arg[0] == '*')
                doc_pop_style(doc);
            else
            {/* Better silently add one if name doesn't exist ... */
                doc_style_t copy = *doc_current_style(doc);
                doc_style_f f = _get_doc_style_f(doc, string_buffer(arg));

                if (f)
                    f(&copy);
                doc_push_style(doc, &copy);
            }
            break;
        case DOC_TAG_VAR:
            _doc_process_var(doc, string_buffer(arg));
            break;
        case DOC_TAG_TAB:
        {
            int pos = atoi(string_buffer(arg)) + doc_current_style(doc)->left;
            if (pos > doc->cursor.x)
                doc_insert_space(doc, pos - doc->cursor.x);
            else
                doc_rollback(doc, doc_pos_create(pos, doc->cursor.y));
            break;
        }
        case DOC_TAG_TOPIC:
        {
            doc_bookmark_ptr mark = malloc(sizeof(doc_bookmark_t));
            mark->name = arg; /* steal ownership */
            arg = NULL;
            mark->pos = doc->cursor;
            vec_add(doc->bookmarks, mark);
            break;
        }
        case DOC_TAG_LINK:
        {
            doc_link_ptr link = malloc(sizeof(doc_link_t));
            int          split = string_chr(arg, 0, '#');
            int          ch = 'a' + int_map_count(doc->links);

            if (split >= 0)
            {
                substring_t left = string_left(arg, split);
                substring_t right = string_right(arg, string_length(arg) - split - 1);

                link->file = substring_copy(&left);
                link->topic = substring_copy(&right);
            }
            else
            {
                link->file = arg; /* steal ownership */
                arg = NULL;
                link->topic = NULL;
            }
            link->location.start = doc->cursor;
            int_map_add(doc->links, ch, link);
            {
                /* TODO: This is flawed. Here's a real world example:
                   "(see below <link:birth.txt#PrimaryStats>)."
                   Can you see the problem? We might line break after "[a]" right
                   before ").". Instead, "[a])." should be treated as the current
                   word. To fix this, we'll need a parser with a token queue
                   that we can push onto, but this raises storage issues.
                */
                string_ptr s = string_alloc_format("<style:link>[%c]</style>", ch);
                doc_insert(doc, string_buffer(s));
                string_free(s);

                link->location.stop = doc->cursor;
            }
            break;
        }
        }

        string_free(arg);
    }
}
示例#8
0
static void _doc_write_html_file(doc_ptr doc, FILE *fp)
{
    doc_pos_t        pos;
    doc_char_ptr     cell;
    byte             old_a = _INVALID_COLOR;
    int              bookmark_idx = 0;
    doc_bookmark_ptr next_bookmark = NULL;
    vec_ptr          links = doc_get_links(doc);
    int              link_idx = 0;
    doc_link_ptr     next_link = NULL;

    if (bookmark_idx < vec_length(doc->bookmarks))
        next_bookmark = vec_get(doc->bookmarks, bookmark_idx);

    if (link_idx < vec_length(links))
        next_link = vec_get(links, link_idx);

    fprintf(fp, "<!DOCTYPE html>\n<html>\n");
    if (string_length(doc->html_header))
        fprintf(fp, "%s\n", string_buffer(doc->html_header));
    fprintf(fp, "<body text=\"#ffffff\" bgcolor=\"#000000\"><pre>\n");

    for (pos.y = 0; pos.y <= doc->cursor.y; pos.y++)
    {
        int cx = doc->width;
        pos.x = 0;
        if (pos.y == doc->cursor.y)
            cx = doc->cursor.x;
        cell = doc_char(doc, pos);

        if (next_bookmark && pos.y == next_bookmark->pos.y)
        {
            fprintf(fp, "<a name=\"%s\"></a>", string_buffer(next_bookmark->name));
            bookmark_idx++;
            if (bookmark_idx < vec_length(doc->bookmarks))
                next_bookmark = vec_get(doc->bookmarks, bookmark_idx);
            else
                next_bookmark = NULL;
        }

        for (; pos.x < cx; pos.x++)
        {
            char c = cell->c;
            byte a = cell->a & 0x0F;

            if (next_link)
            {
                if (doc_pos_compare(next_link->location.start, pos) == 0)
                {
                    string_ptr s;
                    int        pos = string_last_chr(next_link->file, '.');

                    if (pos >= 0)
                    {
                        s = string_copy_sn(string_buffer(next_link->file), pos + 1);
                        string_append_s(s, "html");
                    }
                    else
                        s = string_copy(next_link->file);

                    fprintf(fp, "<a href=\"%s", string_buffer(s));
                    if (next_link->topic)
                        fprintf(fp, "#%s", string_buffer(next_link->topic));
                    fprintf(fp, "\">");

                    string_free(s);
                }
                if (doc_pos_compare(next_link->location.stop, pos) == 0)
                {
                    fprintf(fp, "</a>");
                    link_idx++;
                    if (link_idx < vec_length(links))
                        next_link = vec_get(links, link_idx);
                    else
                        next_link = NULL;
                }
            }

            if (!c) break;

            if (a != old_a && c != ' ')
            {
                if (old_a != _INVALID_COLOR)
                    fprintf(fp, "</font>");
                fprintf(fp,
                    "<font color=\"#%02x%02x%02x\">",
                    angband_color_table[a][1],
                    angband_color_table[a][2],
                    angband_color_table[a][3]
                );
                old_a = a;
            }
            switch (c)
            {
            case '&': fprintf(fp, "&amp;"); break;
            case '<': fprintf(fp, "&lt;"); break;
            case '>': fprintf(fp, "&gt;"); break;
            default:  fprintf(fp, "%c", c); break;
            }
            cell++;
        }
        fputc('\n', fp);
   }
   fprintf(fp, "</font>");
   fprintf(fp, "</pre></body></html>\n");

   vec_free(links);
}