NeoMutt  2024-10-02-7-gd3e66a
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
quoted.h File Reference

Quoted-Email colours. More...

#include "config.h"
#include <stdbool.h>
#include <stddef.h>
#include "core/lib.h"
#include "attr.h"
#include "color.h"
+ Include dependency graph for quoted.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  QuoteStyle
 Style of quoted text. More...
 

Macros

#define COLOR_QUOTES_MAX   10
 Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)
 

Functions

void quoted_colors_init (void)
 Initialise the Quoted colours.
 
void quoted_colors_cleanup (void)
 Reset the quoted-email colours.
 
struct AttrColorquoted_colors_get (int q)
 Return the color of a quote, cycling through the used quotes.
 
int quoted_colors_num_used (void)
 Return the number of used quotes.
 
bool quoted_colors_parse_color (enum ColorId cid, struct AttrColor *ac_val, int q_level, int *rc, struct Buffer *err)
 Parse the 'color quoted' command.
 
enum CommandResult quoted_colors_parse_uncolor (enum ColorId cid, int q_level, struct Buffer *err)
 Parse the 'uncolor quoted' command.
 
struct QuoteStyleqstyle_classify (struct QuoteStyle **quote_list, const char *qptr, size_t length, bool *force_redraw, int *q_level)
 Find a style for a string.
 
void qstyle_free_tree (struct QuoteStyle **quote_list)
 Free an entire tree of QuoteStyle.
 
void qstyle_recolor (struct QuoteStyle *quote_list)
 Recolour quotes after colour changes.
 

Variables

struct AttrColor QuotedColors []
 Array of colours for quoted email text.
 
int NumQuotedColors
 Number of colours for quoted email text.
 

Detailed Description

Quoted-Email colours.

Authors
  • Richard Russon

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file quoted.h.

Macro Definition Documentation

◆ COLOR_QUOTES_MAX

#define COLOR_QUOTES_MAX   10

Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)

Definition at line 36 of file quoted.h.

Function Documentation

◆ quoted_colors_init()

void quoted_colors_init ( void  )

Initialise the Quoted colours.

Definition at line 49 of file quoted.c.

50{
51 for (size_t i = 0; i < COLOR_QUOTES_MAX; i++)
52 {
53 struct AttrColor *ac = &QuotedColors[i];
56 }
58}
#define COLOR_DEFAULT
Definition: color.h:100
int NumQuotedColors
Number of colours for quoted email text.
Definition: quoted.c:44
struct AttrColor QuotedColors[COLOR_QUOTES_MAX]
Array of colours for quoted email text.
Definition: quoted.c:43
#define COLOR_QUOTES_MAX
Ten colours, quoted0..quoted9 (quoted and quoted0 are equivalent)
Definition: quoted.h:36
A curses colour and its attributes.
Definition: attr.h:66
struct ColorElement bg
Background colour.
Definition: attr.h:68
struct ColorElement fg
Foreground colour.
Definition: attr.h:67
color_t color
Colour.
Definition: attr.h:57
+ Here is the caller graph for this function:

◆ quoted_colors_cleanup()

void quoted_colors_cleanup ( void  )

Reset the quoted-email colours.

Definition at line 77 of file quoted.c.

78{
79 color_debug(LL_DEBUG5, "QuotedColors: clean up\n");
80 for (size_t i = 0; i < COLOR_QUOTES_MAX; i++)
81 {
83 }
85}
void attr_color_clear(struct AttrColor *ac)
Free the contents of an AttrColor.
Definition: attr.c:48
static int color_debug(enum LogLevel level, const char *format,...)
Definition: debug.h:53
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quoted_colors_get()

struct AttrColor * quoted_colors_get ( int  q)

Return the color of a quote, cycling through the used quotes.

Parameters
qQuote level
Return values
enumColorId, e.g. MT_COLOR_QUOTED

Definition at line 92 of file quoted.c.

93{
94 if (NumQuotedColors == 0)
95 return NULL;
96 return &QuotedColors[q % NumQuotedColors];
97}
+ Here is the caller graph for this function:

◆ quoted_colors_num_used()

int quoted_colors_num_used ( void  )

Return the number of used quotes.

Return values
numNumber of used quotes

Definition at line 103 of file quoted.c.

104{
105 return NumQuotedColors;
106}
+ Here is the caller graph for this function:

◆ quoted_colors_parse_color()

bool quoted_colors_parse_color ( enum ColorId  cid,
struct AttrColor ac_val,
int  q_level,
int *  rc,
struct Buffer err 
)

Parse the 'color quoted' command.

Parameters
cidColour Id, should be MT_COLOR_QUOTED
ac_valColour value to use
q_levelQuoting depth level
rcReturn code, e.g. MUTT_CMD_SUCCESS
errBuffer for error messages
Return values
trueColour was parsed

Definition at line 117 of file quoted.c.

119{
120 if (cid != MT_COLOR_QUOTED)
121 return false;
122
123 color_debug(LL_DEBUG5, "quoted %d\n", q_level);
124 if (q_level >= COLOR_QUOTES_MAX)
125 {
126 buf_printf(err, _("Maximum quoting level is %d"), COLOR_QUOTES_MAX - 1);
127 return false;
128 }
129
130 if (q_level >= NumQuotedColors)
131 NumQuotedColors = q_level + 1;
132
133 struct AttrColor *ac = &QuotedColors[q_level];
134
135 attr_color_overwrite(ac, ac_val);
136
137 struct CursesColor *cc = ac->curses_color;
138 if (!cc)
140
141 struct Buffer *buf = buf_pool_get();
142 get_colorid_name(cid, buf);
143 color_debug(LL_DEBUG5, "NT_COLOR_SET: %s\n", buf->data);
144 buf_pool_release(&buf);
145
146 if (q_level == 0)
147 {
148 // Copy the colour into the SimpleColors
149 struct AttrColor *ac_quoted = simple_color_get(MT_COLOR_QUOTED);
150 curses_color_free(&ac_quoted->curses_color);
151 *ac_quoted = *ac;
152 ac_quoted->ref_count = 1;
153 if (ac_quoted->curses_color)
154 {
155 ac_quoted->curses_color->ref_count++;
156 curses_color_dump(cc, "curses rc++");
157 }
158 }
159
160 struct EventColor ev_c = { cid, ac };
162
164
165 *rc = MUTT_CMD_SUCCESS;
166 return true;
167}
void attr_color_overwrite(struct AttrColor *ac_old, struct AttrColor *ac_new)
Update an AttrColor in-place.
Definition: attr.c:395
int buf_printf(struct Buffer *buf, const char *fmt,...)
Format a string overwriting a Buffer.
Definition: buffer.c:161
void get_colorid_name(unsigned int cid, struct Buffer *buf)
Get the name of a color id.
Definition: command.c:127
struct Notify * ColorsNotify
Notifications: ColorId, EventColor.
Definition: notify.c:35
struct AttrColor * simple_color_get(enum ColorId cid)
Get the colour of an object by its ID.
Definition: simple.c:88
@ MT_COLOR_QUOTED
Pager: quoted text.
Definition: color.h:63
@ MUTT_CMD_SUCCESS
Success: Command worked.
Definition: command.h:39
void curses_color_free(struct CursesColor **ptr)
Free a CursesColor.
Definition: curses.c:120
void curses_color_dump(struct CursesColor *cc, const char *prefix)
Log one Curses colour.
Definition: debug.c:122
void curses_colors_dump(struct Buffer *buf)
Dump all the Curses colours.
Definition: debug.c:144
#define _(a)
Definition: message.h:28
bool notify_send(struct Notify *notify, enum NotifyType event_type, int event_subtype, void *event_data)
Send out a notification message.
Definition: notify.c:173
@ NT_COLOR_SET
Color has been set.
Definition: notify2.h:41
@ NT_COLOR
Colour has changed, NotifyColor, EventColor.
Definition: notify_type.h:41
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
static int find_highest_used(void)
Find the highest-numbered quotedN in use.
Definition: quoted.c:64
short ref_count
Number of users.
Definition: attr.h:71
struct CursesColor * curses_color
Underlying Curses colour.
Definition: attr.h:70
String manipulation buffer.
Definition: buffer.h:36
char * data
Pointer to data.
Definition: buffer.h:37
Colour in the ncurses palette.
Definition: curses2.h:41
short ref_count
Number of users.
Definition: curses2.h:45
An Event that happened to a Colour.
Definition: notify2.h:53
enum ColorId cid
Colour ID that has changed.
Definition: notify2.h:54
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ quoted_colors_parse_uncolor()

enum CommandResult quoted_colors_parse_uncolor ( enum ColorId  cid,
int  q_level,
struct Buffer err 
)

Parse the 'uncolor quoted' command.

Parameters
cidColour Id, should be MT_COLOR_QUOTED
q_levelQuoting depth level
errBuffer for error messages
Return values
enumCommandResult, e.g. MUTT_CMD_SUCCESS

Definition at line 176 of file quoted.c.

178{
179 color_debug(LL_DEBUG5, "unquoted %d\n", q_level);
180
181 struct AttrColor *ac = &QuotedColors[q_level];
183
185
186 struct EventColor ev_c = { cid, ac };
188
189 return MUTT_CMD_SUCCESS;
190}
@ NT_COLOR_RESET
Color has been reset/removed.
Definition: notify2.h:42
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ qstyle_classify()

struct QuoteStyle * qstyle_classify ( struct QuoteStyle **  quote_list,
const char *  qptr,
size_t  length,
bool *  force_redraw,
int *  q_level 
)

Find a style for a string.

Parameters
[out]quote_listList of quote colours
[in]qptrString to classify
[in]lengthLength of string
[out]force_redrawSet to true if a screen redraw is needed
[out]q_levelQuoting level
Return values
ptrQuoting style

Definition at line 293 of file quoted.c.

295{
296 struct QuoteStyle *q_list = *quote_list;
297 struct QuoteStyle *qc = NULL, *tmp = NULL, *ptr = NULL, *save = NULL;
298 const char *tail_qptr = NULL;
299 size_t offset, tail_lng;
300 int index = -1;
301
302 /* classify quoting prefix */
303 while (q_list)
304 {
305 if (length <= q_list->prefix_len)
306 {
307 /* case 1: check the top level nodes */
308
309 if (mutt_strn_equal(qptr, q_list->prefix, length))
310 {
311 if (length == q_list->prefix_len)
312 return q_list; /* same prefix: return the current class */
313
314 /* found shorter prefix */
315 if (tmp)
316 {
317 /* found another branch for which tmp is a shorter prefix */
318
319 /* save the next sibling for later */
320 save = q_list->next;
321
322 /* unlink q_list from the top level list */
323 if (q_list->next)
324 q_list->next->prev = q_list->prev;
325 if (q_list->prev)
326 q_list->prev->next = q_list->next;
327
328 /* at this point, we have a tmp->down; link q_list to it */
329 ptr = tmp->down;
330 /* sibling order is important here, q_list should be linked last */
331 while (ptr->next)
332 ptr = ptr->next;
333 ptr->next = q_list;
334 q_list->next = NULL;
335 q_list->prev = ptr;
336 q_list->up = tmp;
337
338 index = q_list->quote_n;
339
340 /* next class to test; as above, we shouldn't go down */
341 q_list = save;
342 }
343 else
344 {
345 /* add a node above q_list */
346 tmp = qstyle_new();
347 tmp->prefix = mutt_strn_dup(qptr, length);
348 tmp->prefix_len = length;
349
350 /* replace q_list by tmp in the top level list */
351 if (q_list->next)
352 {
353 tmp->next = q_list->next;
354 q_list->next->prev = tmp;
355 }
356 if (q_list->prev)
357 {
358 tmp->prev = q_list->prev;
359 q_list->prev->next = tmp;
360 }
361
362 /* make q_list a child of tmp */
363 tmp->down = q_list;
364 q_list->up = tmp;
365
366 /* q_list has no siblings for now */
367 q_list->next = NULL;
368 q_list->prev = NULL;
369
370 /* update the root if necessary */
371 if (q_list == *quote_list)
372 *quote_list = tmp;
373
374 index = q_list->quote_n;
375
376 /* tmp should be the return class too */
377 qc = tmp;
378
379 /* next class to test; if tmp is a shorter prefix for another
380 * node, that node can only be in the top level list, so don't
381 * go down after this point */
382 q_list = tmp->next;
383 }
384
385 /* we found a shorter prefix, so certain quotes have changed classes */
386 *force_redraw = true;
387 continue;
388 }
389 else
390 {
391 /* shorter, but not a substring of the current class: try next */
392 q_list = q_list->next;
393 continue;
394 }
395 }
396 else
397 {
398 /* case 2: try subclassing the current top level node */
399
400 /* tmp != NULL means we already found a shorter prefix at case 1 */
401 if (!tmp && mutt_strn_equal(qptr, q_list->prefix, q_list->prefix_len))
402 {
403 /* ok, it's a subclass somewhere on this branch */
404
405 ptr = q_list;
406 offset = q_list->prefix_len;
407
408 q_list = q_list->down;
409 tail_lng = length - offset;
410 tail_qptr = qptr + offset;
411
412 while (q_list)
413 {
414 if (length <= q_list->prefix_len)
415 {
416 if (mutt_strn_equal(tail_qptr, (q_list->prefix) + offset, tail_lng))
417 {
418 /* same prefix: return the current class */
419 if (length == q_list->prefix_len)
420 return q_list;
421
422 /* found shorter common prefix */
423 if (!tmp)
424 {
425 /* add a node above q_list */
426 tmp = qstyle_new();
427 tmp->prefix = mutt_strn_dup(qptr, length);
428 tmp->prefix_len = length;
429
430 /* replace q_list by tmp */
431 if (q_list->next)
432 {
433 tmp->next = q_list->next;
434 q_list->next->prev = tmp;
435 }
436 if (q_list->prev)
437 {
438 tmp->prev = q_list->prev;
439 q_list->prev->next = tmp;
440 }
441
442 /* make q_list a child of tmp */
443 tmp->down = q_list;
444 tmp->up = q_list->up;
445 q_list->up = tmp;
446 if (tmp->up->down == q_list)
447 tmp->up->down = tmp;
448
449 /* q_list has no siblings */
450 q_list->next = NULL;
451 q_list->prev = NULL;
452
453 index = q_list->quote_n;
454
455 /* tmp should be the return class too */
456 qc = tmp;
457
458 /* next class to test */
459 q_list = tmp->next;
460 }
461 else
462 {
463 /* found another branch for which tmp is a shorter prefix */
464
465 /* save the next sibling for later */
466 save = q_list->next;
467
468 /* unlink q_list from the top level list */
469 if (q_list->next)
470 q_list->next->prev = q_list->prev;
471 if (q_list->prev)
472 q_list->prev->next = q_list->next;
473
474 /* at this point, we have a tmp->down; link q_list to it */
475 ptr = tmp->down;
476 while (ptr->next)
477 ptr = ptr->next;
478 ptr->next = q_list;
479 q_list->next = NULL;
480 q_list->prev = ptr;
481 q_list->up = tmp;
482
483 index = q_list->quote_n;
484
485 /* next class to test */
486 q_list = save;
487 }
488
489 /* we found a shorter prefix, so we need a redraw */
490 *force_redraw = true;
491 continue;
492 }
493 else
494 {
495 q_list = q_list->next;
496 continue;
497 }
498 }
499 else
500 {
501 /* longer than the current prefix: try subclassing it */
502 if (!tmp && mutt_strn_equal(tail_qptr, (q_list->prefix) + offset,
503 q_list->prefix_len - offset))
504 {
505 /* still a subclass: go down one level */
506 ptr = q_list;
507 offset = q_list->prefix_len;
508
509 q_list = q_list->down;
510 tail_lng = length - offset;
511 tail_qptr = qptr + offset;
512
513 continue;
514 }
515 else
516 {
517 /* nope, try the next prefix */
518 q_list = q_list->next;
519 continue;
520 }
521 }
522 }
523
524 /* still not found so far: add it as a sibling to the current node */
525 if (!qc)
526 {
527 tmp = qstyle_new();
528 tmp->prefix = mutt_strn_dup(qptr, length);
529 tmp->prefix_len = length;
530
531 if (ptr->down)
532 {
533 tmp->next = ptr->down;
534 ptr->down->prev = tmp;
535 }
536 ptr->down = tmp;
537 tmp->up = ptr;
538
539 tmp->quote_n = (*q_level)++;
540 tmp->attr_color = quoted_colors_get(tmp->quote_n);
541
542 return tmp;
543 }
544 else
545 {
546 if (index != -1)
547 qstyle_insert(*quote_list, tmp, index, q_level);
548
549 return qc;
550 }
551 }
552 else
553 {
554 /* nope, try the next prefix */
555 q_list = q_list->next;
556 continue;
557 }
558 }
559 }
560
561 if (!qc)
562 {
563 /* not found so far: add it as a top level class */
564 qc = qstyle_new();
565 qc->prefix = mutt_strn_dup(qptr, length);
566 qc->prefix_len = length;
567 qc->quote_n = (*q_level)++;
569
570 if (*quote_list)
571 {
572 if ((*quote_list)->next)
573 {
574 qc->next = (*quote_list)->next;
575 qc->next->prev = qc;
576 }
577 (*quote_list)->next = qc;
578 qc->prev = *quote_list;
579 }
580 else
581 {
582 *quote_list = qc;
583 }
584 }
585
586 if (index != -1)
587 qstyle_insert(*quote_list, tmp, index, q_level);
588
589 return qc;
590}
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition: string.c:380
bool mutt_strn_equal(const char *a, const char *b, size_t num)
Check for equality of two strings (to a maximum), safely.
Definition: string.c:425
struct AttrColor * quoted_colors_get(int q)
Return the color of a quote, cycling through the used quotes.
Definition: quoted.c:92
static void qstyle_insert(struct QuoteStyle *quote_list, struct QuoteStyle *new_class, int index, int *q_level)
Insert a new quote colour class into a list.
Definition: quoted.c:245
static struct QuoteStyle * qstyle_new(void)
Create a new QuoteStyle.
Definition: quoted.c:233
Style of quoted text.
Definition: quoted.h:67
struct AttrColor * attr_color
Colour and attribute of the text.
Definition: quoted.h:69
struct QuoteStyle * next
Different quoting styles at the same level.
Definition: quoted.h:72
struct QuoteStyle * up
Definition: quoted.h:73
size_t prefix_len
Length of the prefix string.
Definition: quoted.h:71
struct QuoteStyle * prev
Definition: quoted.h:72
char * prefix
Prefix string, e.g. "> ".
Definition: quoted.h:70
struct QuoteStyle * down
Parent (less quoted) and child (more quoted) levels.
Definition: quoted.h:73
int quote_n
The quoteN colour index for this level.
Definition: quoted.h:68
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ qstyle_free_tree()

void qstyle_free_tree ( struct QuoteStyle **  quote_list)

Free an entire tree of QuoteStyle.

Parameters
[out]quote_listQuote list to free
Note
Use qstyle_free() to free a single object

Definition at line 215 of file quoted.c.

216{
217 struct QuoteStyle *next = NULL;
218
219 while (*quote_list)
220 {
221 if ((*quote_list)->down)
222 qstyle_free_tree(&((*quote_list)->down));
223 next = (*quote_list)->next;
224 qstyle_free(quote_list);
225 *quote_list = next;
226 }
227}
void qstyle_free_tree(struct QuoteStyle **quote_list)
Free an entire tree of QuoteStyle.
Definition: quoted.c:215
static void qstyle_free(struct QuoteStyle **ptr)
Free a single QuoteStyle object.
Definition: quoted.c:198
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ qstyle_recolor()

void qstyle_recolor ( struct QuoteStyle quote_list)

Recolour quotes after colour changes.

Parameters
quote_listList of quote colours

Definition at line 621 of file quoted.c.

622{
623 if (!quote_list)
624 return;
625
626 int num = quoted_colors_num_used();
627 int cur = 0;
628
629 qstyle_recurse(quote_list, num, &cur);
630}
int quoted_colors_num_used(void)
Return the number of used quotes.
Definition: quoted.c:103
static void qstyle_recurse(struct QuoteStyle *quote_list, int num_qlevel, int *cur_qlevel)
Update the quoting styles after colour changes.
Definition: quoted.c:598
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ QuotedColors

struct AttrColor QuotedColors[]
extern

Array of colours for quoted email text.

Definition at line 43 of file quoted.c.

◆ NumQuotedColors

int NumQuotedColors
extern

Number of colours for quoted email text.

Definition at line 44 of file quoted.c.