%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Read-article-trail %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % How many articles to maintain in the trail variable max_read_history = 50; variable read_history = String_Type [max_read_history]; variable next_slot_to_use = 0; variable slot_being_shown = 0; variable slots_in_use = 0; % % read_history: [ N N N N N X X X X X N N N ] (circular buffer, X are valid) % ^ % \- next_slot_to_use points here % slot_being_shown must point at an X. slots_in_use is 5 here. define show_article_in_slot() { %fprintf(stderr, "showing article %d (%s)\n",slot_being_shown, read_history[slot_being_shown]); () = locate_header_by_msgid (read_history[slot_being_shown],0); call ("article_pagedn"); } define go_back_one_read_article() { %fprintf(stderr, "backward\n"); variable d = next_slot_to_use - slot_being_shown; if (d < 0) { d += max_read_history; } % ASSERT: 0 <= d <= slots_in_use % (and d == 0 if and only if slots_in_use == 0) if (d == slots_in_use) { % can't go any further backward return; } if (slot_being_shown == 0) { slot_being_shown = max_read_history; } slot_being_shown--; show_article_in_slot(); } define go_forward_one_read_article() { %fprintf(stderr, "forward\n"); variable d = next_slot_to_use - slot_being_shown; if (d < 0) { d += max_read_history; } % ASSERT: 0 <= d <= slots_in_use % (and d == 0 if and only if slots_in_use == 0) if (d <= 1) { % can't go any further forward return; } slot_being_shown++; if (slot_being_shown == max_read_history) { slot_being_shown = 0; } show_article_in_slot(); } define add_article_to_read_history(art) { % Just add this article to the end of the history list. %fprintf(stderr, "adding article %s\n", art); read_history[next_slot_to_use] = art; slot_being_shown = next_slot_to_use; next_slot_to_use++; if (next_slot_to_use == max_read_history) { next_slot_to_use = 0; } if (slots_in_use < max_read_history) { slots_in_use++; } } define maybe_add_article_to_read_history() { % Add this article to the history only if it isn't there % already. [The most common case being that we've just hit '<' % to go back in the history; we definitely don't want to re-add % the page to the end of the list!] variable this_article = extract_article_header ("Message-Id"); %fprintf(stderr,"thinking about adding article %s\n", this_article); variable h = next_slot_to_use; variable i = 0; while (i < slots_in_use) { i++; if (h == 0) { h = max_read_history; } h--; if (read_history[h] == this_article) { return; } } add_article_to_read_history(this_article); } define clear_read_history() { next_slot_to_use = 0; slot_being_shown = 0; slots_in_use = 0; } %%%%%%%%%%%%%%%%%%%%%%%%%%%%% % To use: %%%%%%%%%%%%%%%%%%%%%%%%%%%%% define read_article_hook() { maybe_add_article_to_read_history(); } define article_mode_hook() { clear_read_history(); } definekey ("go_back_one_read_article", "<", "article"); definekey ("go_forward_one_read_article", ">", "article");