diff -rc alpine-2.24/alpine/confscroll.c alpine-2.24.colortext/alpine/confscroll.c *** alpine-2.24/alpine/confscroll.c 2020-10-10 00:24:28.216554908 -0600 --- alpine-2.24.colortext/alpine/confscroll.c 2020-10-10 00:27:00.384432838 -0600 *************** *** 5248,5253 **** --- 5248,5256 ---- clear_index_cache(ps->mail_stream, 0); } + else if(var == &ps->vars[V_SPECIAL_TEXT]){ + regex_pattern(ps->VAR_SPECIAL_TEXT); + } else if(var == &ps->vars[V_INIT_CMD_LIST]){ if(!revert) q_status_message(SM_ASYNC, 0, 3, diff -rc alpine-2.24/pith/conf.c alpine-2.24.colortext/pith/conf.c *** alpine-2.24/pith/conf.c 2020-10-10 00:24:28.204554602 -0600 --- alpine-2.24.colortext/pith/conf.c 2020-10-10 00:27:00.388432939 -0600 *************** *** 233,238 **** --- 233,240 ---- CONF_TXT_T cf_text_fillcol[] = "Specifies the column of the screen where the composer should wrap."; + CONF_TXT_T cf_special_text_color[] = "Specifies a comma separated list of text and regular expresions that Pine\n# will highlight"; + CONF_TXT_T cf_text_replystr[] = "Specifies the string to insert when replying to a message."; CONF_TXT_T cf_text_quotereplstr[] = "Specifies the string to replace quotes with when viewing a message."; *************** *** 587,592 **** --- 589,596 ---- #endif /* _WINDOWS */ {"composer-wrap-column", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, NULL, cf_text_fillcol}, + {"special-text-color", 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, + NULL, cf_special_text_color}, {"reply-indent-string", 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, NULL, cf_text_replystr}, {"reply-leadin", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, *************** *** 862,867 **** --- 866,873 ---- {"incoming-unseen-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, {"signature-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, {"signature-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, + {"special-text-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, + {"special-text-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, {"prompt-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, {"prompt-background-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, {"header-general-foreground-color", 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0}, *************** *** 2111,2116 **** --- 2117,2124 ---- set_current_val(&vars[V_DICTIONARY], TRUE, TRUE); #endif /* _WINDOWS */ set_current_val(&vars[V_IMAGE_VIEWER], TRUE, TRUE); + set_current_val(&vars[V_SPECIAL_TEXT], TRUE, TRUE); + regex_pattern(VAR_SPECIAL_TEXT); set_current_val(&vars[V_BROWSER], TRUE, TRUE); set_current_val(&vars[V_HISTORY], TRUE, TRUE); set_current_val(&vars[V_SMTP_SERVER], TRUE, TRUE); *************** *** 6677,6682 **** --- 6685,6691 ---- set_color_val(&vars[V_IND_OP_FORE_COLOR], 0); set_color_val(&vars[V_INCUNSEEN_FORE_COLOR], 0); set_color_val(&vars[V_SIGNATURE_FORE_COLOR], 0); + set_color_val(&vars[V_SPECIAL_TEXT_FORE_COLOR], 0); set_current_val(&ps->vars[V_INDEX_TOKEN_COLORS], TRUE, TRUE); set_current_val(&ps->vars[V_VIEW_HDR_COLORS], TRUE, TRUE); *************** *** 7926,7931 **** --- 7935,7942 ---- return(h_config_scroll_margin); case V_DEADLETS : return(h_config_deadlets); + case V_SPECIAL_TEXT : + return(h_config_special_text_to_color); case V_FILLCOL : return(h_config_composer_wrap_column); case V_TCPOPENTIMEO : *************** *** 8107,8112 **** --- 8118,8126 ---- case V_SIGNATURE_FORE_COLOR : case V_SIGNATURE_BACK_COLOR : return(h_config_signature_color); + case V_SPECIAL_TEXT_FORE_COLOR : + case V_SPECIAL_TEXT_BACK_COLOR : + return(h_config_special_text_color); case V_PROMPT_FORE_COLOR : case V_PROMPT_BACK_COLOR : return(h_config_prompt_color); diff -rc alpine-2.24/pith/conf.h alpine-2.24.colortext/pith/conf.h *** alpine-2.24/pith/conf.h 2020-10-10 00:24:28.204554602 -0600 --- alpine-2.24.colortext/pith/conf.h 2020-10-10 00:27:00.388432939 -0600 *************** *** 175,180 **** --- 175,182 ---- #define VAR_DICTIONARY vars[V_DICTIONARY].current_val.l #define GLO_DICTIONARY vars[V_DICTIONARY].global_val.l #endif /* _WINDOWS */ + #define VAR_SPECIAL_TEXT vars[V_SPECIAL_TEXT].current_val.l + #define GLO_SPECIAL_TEXT vars[V_SPECIAL_TEXT].global_val.l #define VAR_FILLCOL vars[V_FILLCOL].current_val.p #define GLO_FILLCOL vars[V_FILLCOL].global_val.p #define VAR_DEADLETS vars[V_DEADLETS].current_val.p *************** *** 474,479 **** --- 476,483 ---- #define GLO_SIGNATURE_FORE_COLOR vars[V_SIGNATURE_FORE_COLOR].global_val.p #define VAR_SIGNATURE_BACK_COLOR vars[V_SIGNATURE_BACK_COLOR].current_val.p #define GLO_SIGNATURE_BACK_COLOR vars[V_SIGNATURE_BACK_COLOR].global_val.p + #define VAR_SPECIAL_TEXT_FORE_COLOR vars[V_SPECIAL_TEXT_FORE_COLOR].current_val.p + #define VAR_SPECIAL_TEXT_BACK_COLOR vars[V_SPECIAL_TEXT_BACK_COLOR].current_val.p #define VAR_PROMPT_FORE_COLOR vars[V_PROMPT_FORE_COLOR].current_val.p #define VAR_PROMPT_BACK_COLOR vars[V_PROMPT_BACK_COLOR].current_val.p #define VAR_VIEW_HDR_COLORS vars[V_VIEW_HDR_COLORS].current_val.l diff -rc alpine-2.24/pith/conftype.h alpine-2.24.colortext/pith/conftype.h *** alpine-2.24/pith/conftype.h 2020-10-10 00:24:28.204554602 -0600 --- alpine-2.24.colortext/pith/conftype.h 2020-10-10 00:27:00.388432939 -0600 *************** *** 83,88 **** --- 83,89 ---- , V_DICTIONARY #endif /* _WINDOWS */ , V_FILLCOL + , V_SPECIAL_TEXT , V_REPLY_STRING , V_REPLY_INTRO , V_QUOTE_REPLACE_STRING *************** *** 243,248 **** --- 244,251 ---- , V_INCUNSEEN_BACK_COLOR , V_SIGNATURE_FORE_COLOR , V_SIGNATURE_BACK_COLOR + , V_SPECIAL_TEXT_FORE_COLOR + , V_SPECIAL_TEXT_BACK_COLOR , V_PROMPT_FORE_COLOR , V_PROMPT_BACK_COLOR , V_HEADER_GENERAL_FORE_COLOR diff -rc alpine-2.24/pith/mailview.c alpine-2.24.colortext/pith/mailview.c *** alpine-2.24/pith/mailview.c 2020-10-10 00:24:28.204554602 -0600 --- alpine-2.24.colortext/pith/mailview.c 2020-10-10 00:27:00.388432939 -0600 *************** *** 638,643 **** --- 638,651 ---- if((flgs & FM_DISPLAY) && !(flgs & FM_NOCOLOR) && pico_usingcolor() + && ps_global->VAR_SPECIAL_TEXT_FORE_COLOR + && ps_global->VAR_SPECIAL_TEXT_BACK_COLOR){ + gf_link_filter(gf_line_test, gf_line_test_opt(color_this_text, NULL)); + } + + if((flgs & FM_DISPLAY) + && !(flgs & FM_NOCOLOR) + && pico_usingcolor() && ps_global->VAR_SIGNATURE_FORE_COLOR && ps_global->VAR_SIGNATURE_BACK_COLOR){ gf_link_filter(gf_line_test, gf_line_test_opt(color_signature, &is_in_sig)); *************** *** 2870,2875 **** --- 2878,3067 ---- return(color_pair); } + void + interval_free(IVAL_S **ival) + { + if (!(*ival)) + return; + + if ((*ival)->next) + interval_free(&((*ival)->next)); + + fs_give((void **)(ival)); + } + + IVAL_S * + compute_interval (char *string, int endm) + { + IVAL_S *ival = NULL; + regmatch_t pmatch; + + if(ps_global->paterror == 0 && + regexec(&ps_global->colorpat, string + endm, 1, &pmatch, 0) == 0){ + ival = (IVAL_S *) fs_get(sizeof(IVAL_S)); + ival->start = endm + pmatch.rm_so; + ival->end = endm + pmatch.rm_eo; + ival->next = compute_interval(string, ival->end); + } + return ival; + } + + void + regex_pattern(char **plist) + { + int i = 0, j = 0, len = 0; + char *pattern = NULL; + regex_t preg; + + if(ps_global->paterror == 0) + regfree(&ps_global->colorpat); + + if(plist && *plist && *plist){ + for (i = 0; plist[i] && plist[i][0]; i++) + len += strlen(plist[i]) + 1; + pattern = (char *) fs_get(len * sizeof(char)); + *pattern = '\0'; + for (j = 0; j < i; j++){ + strcat(pattern, plist[j]); + strcat(pattern, (j < i - 1) ? "|" : ""); + } + if ((ps_global->paterror = regcomp(&preg, pattern, REG_EXTENDED)) != 0) + regfree(&preg); + else + ps_global->colorpat = preg; + } + if(pattern) + fs_give((void **)&pattern); + } + + LT_INS_S ** + insert_color_special_text(LT_INS_S **ins, char **p, IVAL_S *ival, int last_end, + COLOR_PAIR *col) + { + struct variable *vars = ps_global->vars; + + if (ival){ + *p += ival->start - last_end; + ins = gf_line_test_new_ins(ins, *p, color_embed(col->fg, col->bg), + (2 * RGBLEN) + 4); + *p += ival->end - ival->start; + ins = gf_line_test_new_ins(ins, *p, color_embed(VAR_NORM_FORE_COLOR, + VAR_NORM_BACK_COLOR), (2 * RGBLEN) + 4); + ins = insert_color_special_text(ins, p, ival->next, ival->end, col); + } + return ins; + } + + int + length_color(char *p, int begin_color) + { + int len = 0, done = begin_color ? 0 : -1; + char *orig = p; + + while (*p && done <= 0){ + switch(*p++){ + case TAG_HANDLE : + p += *p + 1; + done++; + break; + + case TAG_FGCOLOR : + case TAG_BGCOLOR : + p += RGBLEN; + if (!begin_color) + done++; + break; + + default : + break; + } + } + len = p - orig; + return len; + } + + int + any_color_in_string(char *p) + { + int rv = 0; + char *orig = p; + while (*p && !rv) + if (*p++ == TAG_EMBED) + rv = p - orig; + return rv; + } + + void + remove_spaces_ival(IVAL_S **ivalp, char *p) + { + IVAL_S *ival; + int i; + if (!ivalp || !*ivalp) + return; + ival = *ivalp; + for (i = 0; isspace((unsigned char) p[ival->start + i]); i++); + if (ival->start + i < ival->end) /* do not do this if match only spaces */ + ival->start += i; + else + return; + for (i = 0; isspace((unsigned char) p[ival->end - i - 1]); i++); + ival->end -= i; + if (ival->next) + remove_spaces_ival(&(ival->next), p); + } + + int + color_this_text(long linenum, char *line, LT_INS_S **ins, void *local) + { + struct variable *vars = ps_global->vars; + COLOR_PAIR *col = NULL; + char *p; + int i = 0; + static char *pattern = NULL; + + /* select_quote(linenum, line, ins, (void *) &i); + for (i = 0; tmp_20k_buf[i] != '\0'; i++); */ + p = line + i; + + if(VAR_SPECIAL_TEXT_FORE_COLOR && VAR_SPECIAL_TEXT_BACK_COLOR + && (col = new_color_pair(VAR_SPECIAL_TEXT_FORE_COLOR, + VAR_SPECIAL_TEXT_BACK_COLOR)) + && !pico_is_good_colorpair(col)) + free_color_pair(&col); + + if(ps_global->VAR_SPECIAL_TEXT && *ps_global->VAR_SPECIAL_TEXT + && **ps_global->VAR_SPECIAL_TEXT && col){ + IVAL_S *ival; + int done = 0, begin_color = 0; + + while (!done){ + if (i = any_color_in_string(p)){ + begin_color = (begin_color + 1) % 2; + if (begin_color){ + p[i - 1] = '\0'; + ival = compute_interval(p, 0); + remove_spaces_ival(&ival, p); + p[i - 1] = TAG_EMBED; + ins = insert_color_special_text(ins, &p, ival, 0, col); + } + for (;*p++ != TAG_EMBED; ); + p += length_color(p, begin_color); + } + else{ + ival = compute_interval(p, 0); + remove_spaces_ival(&ival, p); + ins = insert_color_special_text(ins, &p, ival, 0, col); + done++; + } + interval_free(&ival); + if (!*p) + done++; + } + free_color_pair(&col); + } + + return 0; + } /* * The argument fieldname is something like "Subject:..." or "Subject". diff -rc alpine-2.24/pith/mailview.h alpine-2.24.colortext/pith/mailview.h *** alpine-2.24/pith/mailview.h 2020-10-10 00:24:28.204554602 -0600 --- alpine-2.24.colortext/pith/mailview.h 2020-10-10 00:27:00.388432939 -0600 *************** *** 30,35 **** --- 30,41 ---- #include "../pith/color.h" + typedef struct IVAL { + int start; + int end; + struct IVAL *next; + } IVAL_S; + /* format_message flags */ #define FM_DISPLAY 0x0001 /* result is headed for display */ #define FM_NEW_MESS 0x0002 /* a new message so zero out attachment descrip */ *************** *** 130,135 **** --- 136,150 ---- int url_hilite(long, char *, LT_INS_S **, void *); int handle_start_color(char *, size_t, int *, int); int handle_end_color(char *, size_t, int *); + IVAL_S *compute_interval(char *, int); + void remove_spaces_ival(IVAL_S **, char *); + void interval_free(IVAL_S **); + void regex_pattern(char **); + LT_INS_S **insert_color_special_text(LT_INS_S **, char **, IVAL_S *, + int, COLOR_PAIR *); + int any_color_in_string(char *); + int length_color(char *, int); + int color_this_text(long, char *, LT_INS_S **, void *); /* * BUG: BELOW IS UNIX/PC ONLY since config'd browser means nothing to webpine diff -rc alpine-2.24/pith/pine.hlp alpine-2.24.colortext/pith/pine.hlp *** alpine-2.24/pith/pine.hlp 2020-10-10 00:24:28.204554602 -0600 --- alpine-2.24.colortext/pith/pine.hlp 2020-10-10 00:27:00.408433449 -0600 *************** *** 4975,4980 **** --- 4975,4981 ----