NeoMutt  2025-12-11-1009-ga75d9e
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
qstyle.h File Reference

Quoted style. More...

#include <stdbool.h>
#include <stddef.h>
Include dependency graph for qstyle.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...

Functions

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.

Detailed Description

Quoted style.

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 qstyle.h.

Function Documentation

◆ 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 136 of file qstyle.c.

138{
139 struct QuoteStyle *q_list = *quote_list;
140 struct QuoteStyle *qc = NULL;
141 struct QuoteStyle *tmp = NULL;
142 struct QuoteStyle *ptr = NULL;
143 struct QuoteStyle *save = NULL;
144 const char *tail_qptr = NULL;
145 size_t offset;
146 size_t tail_lng;
147 int index = -1;
148
149 /* classify quoting prefix */
150 while (q_list)
151 {
152 if (length <= q_list->prefix_len)
153 {
154 /* case 1: check the top level nodes */
155
156 if (mutt_strn_equal(qptr, q_list->prefix, length))
157 {
158 if (length == q_list->prefix_len)
159 return q_list; /* same prefix: return the current class */
160
161 /* found shorter prefix */
162 if (tmp)
163 {
164 /* found another branch for which tmp is a shorter prefix */
165
166 /* save the next sibling for later */
167 save = q_list->next;
168
169 /* unlink q_list from the top level list */
170 if (q_list->next)
171 q_list->next->prev = q_list->prev;
172 if (q_list->prev)
173 q_list->prev->next = q_list->next;
174
175 /* at this point, we have a tmp->down; link q_list to it */
176 ptr = tmp->down;
177 /* sibling order is important here, q_list should be linked last */
178 while (ptr->next)
179 ptr = ptr->next;
180 ptr->next = q_list;
181 q_list->next = NULL;
182 q_list->prev = ptr;
183 q_list->up = tmp;
184
185 index = q_list->quote_n;
186
187 /* next class to test; as above, we shouldn't go down */
188 q_list = save;
189 }
190 else
191 {
192 /* add a node above q_list */
193 tmp = qstyle_new();
194 tmp->prefix = mutt_strn_dup(qptr, length);
195 tmp->prefix_len = length;
196
197 /* replace q_list by tmp in the top level list */
198 if (q_list->next)
199 {
200 tmp->next = q_list->next;
201 q_list->next->prev = tmp;
202 }
203 if (q_list->prev)
204 {
205 tmp->prev = q_list->prev;
206 q_list->prev->next = tmp;
207 }
208
209 /* make q_list a child of tmp */
210 tmp->down = q_list;
211 q_list->up = tmp;
212
213 /* q_list has no siblings for now */
214 q_list->next = NULL;
215 q_list->prev = NULL;
216
217 /* update the root if necessary */
218 if (q_list == *quote_list)
219 *quote_list = tmp;
220
221 index = q_list->quote_n;
222
223 /* tmp should be the return class too */
224 qc = tmp;
225
226 /* next class to test; if tmp is a shorter prefix for another
227 * node, that node can only be in the top level list, so don't
228 * go down after this point */
229 q_list = tmp->next;
230 }
231
232 /* we found a shorter prefix, so certain quotes have changed classes */
233 *force_redraw = true;
234 continue;
235 }
236 else
237 {
238 /* shorter, but not a substring of the current class: try next */
239 q_list = q_list->next;
240 continue;
241 }
242 }
243 else
244 {
245 /* case 2: try subclassing the current top level node */
246
247 /* tmp != NULL means we already found a shorter prefix at case 1 */
248 if (!tmp && mutt_strn_equal(qptr, q_list->prefix, q_list->prefix_len))
249 {
250 /* ok, it's a subclass somewhere on this branch */
251
252 ptr = q_list;
253 offset = q_list->prefix_len;
254
255 q_list = q_list->down;
256 tail_lng = length - offset;
257 tail_qptr = qptr + offset;
258
259 while (q_list)
260 {
261 if (length <= q_list->prefix_len)
262 {
263 if (mutt_strn_equal(tail_qptr, (q_list->prefix) + offset, tail_lng))
264 {
265 /* same prefix: return the current class */
266 if (length == q_list->prefix_len)
267 return q_list;
268
269 /* found shorter common prefix */
270 if (!tmp)
271 {
272 /* add a node above q_list */
273 tmp = qstyle_new();
274 tmp->prefix = mutt_strn_dup(qptr, length);
275 tmp->prefix_len = length;
276
277 /* replace q_list by tmp */
278 if (q_list->next)
279 {
280 tmp->next = q_list->next;
281 q_list->next->prev = tmp;
282 }
283 if (q_list->prev)
284 {
285 tmp->prev = q_list->prev;
286 q_list->prev->next = tmp;
287 }
288
289 /* make q_list a child of tmp */
290 tmp->down = q_list;
291 tmp->up = q_list->up;
292 q_list->up = tmp;
293 if (tmp->up->down == q_list)
294 tmp->up->down = tmp;
295
296 /* q_list has no siblings */
297 q_list->next = NULL;
298 q_list->prev = NULL;
299
300 index = q_list->quote_n;
301
302 /* tmp should be the return class too */
303 qc = tmp;
304
305 /* next class to test */
306 q_list = tmp->next;
307 }
308 else
309 {
310 /* found another branch for which tmp is a shorter prefix */
311
312 /* save the next sibling for later */
313 save = q_list->next;
314
315 /* unlink q_list from the top level list */
316 if (q_list->next)
317 q_list->next->prev = q_list->prev;
318 if (q_list->prev)
319 q_list->prev->next = q_list->next;
320
321 /* at this point, we have a tmp->down; link q_list to it */
322 ptr = tmp->down;
323 while (ptr->next)
324 ptr = ptr->next;
325 ptr->next = q_list;
326 q_list->next = NULL;
327 q_list->prev = ptr;
328 q_list->up = tmp;
329
330 index = q_list->quote_n;
331
332 /* next class to test */
333 q_list = save;
334 }
335
336 /* we found a shorter prefix, so we need a redraw */
337 *force_redraw = true;
338 continue;
339 }
340 else
341 {
342 q_list = q_list->next;
343 continue;
344 }
345 }
346 else
347 {
348 /* longer than the current prefix: try subclassing it */
349 if (!tmp && mutt_strn_equal(tail_qptr, (q_list->prefix) + offset,
350 q_list->prefix_len - offset))
351 {
352 /* still a subclass: go down one level */
353 ptr = q_list;
354 offset = q_list->prefix_len;
355
356 q_list = q_list->down;
357 tail_lng = length - offset;
358 tail_qptr = qptr + offset;
359
360 continue;
361 }
362 else
363 {
364 /* nope, try the next prefix */
365 q_list = q_list->next;
366 continue;
367 }
368 }
369 }
370
371 /* still not found so far: add it as a sibling to the current node */
372 if (!qc)
373 {
374 tmp = qstyle_new();
375 tmp->prefix = mutt_strn_dup(qptr, length);
376 tmp->prefix_len = length;
377
378 if (ptr->down)
379 {
380 tmp->next = ptr->down;
381 ptr->down->prev = tmp;
382 }
383 ptr->down = tmp;
384 tmp->up = ptr;
385
386 tmp->quote_n = (*q_level)++;
388
389 return tmp;
390 }
391 else
392 {
393 if (index != -1)
394 qstyle_insert(*quote_list, tmp, index, q_level);
395
396 return qc;
397 }
398 }
399 else
400 {
401 /* nope, try the next prefix */
402 q_list = q_list->next;
403 continue;
404 }
405 }
406 }
407
408 if (!qc)
409 {
410 /* not found so far: add it as a top level class */
411 qc = qstyle_new();
412 qc->prefix = mutt_strn_dup(qptr, length);
413 qc->prefix_len = length;
414 qc->quote_n = (*q_level)++;
416
417 if (*quote_list)
418 {
419 if ((*quote_list)->next)
420 {
421 qc->next = (*quote_list)->next;
422 qc->next->prev = qc;
423 }
424 (*quote_list)->next = qc;
425 qc->prev = *quote_list;
426 }
427 else
428 {
429 *quote_list = qc;
430 }
431 }
432
433 if (index != -1)
434 qstyle_insert(*quote_list, tmp, index, q_level);
435
436 return qc;
437}
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition string.c:384
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:429
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 qstyle.c:88
static struct QuoteStyle * qstyle_new(void)
Create a new QuoteStyle.
Definition qstyle.c:76
struct AttrColor * quoted_colors_get(int q)
Return the color of a quote, cycling through the used quotes.
Definition quoted.c:102
Style of quoted text.
Definition qstyle.h:55
struct AttrColor * attr_color
Colour and attribute of the text.
Definition qstyle.h:57
struct QuoteStyle * next
Different quoting styles at the same level.
Definition qstyle.h:60
struct QuoteStyle * up
Definition qstyle.h:61
size_t prefix_len
Length of the prefix string.
Definition qstyle.h:59
struct QuoteStyle * prev
Definition qstyle.h:60
char * prefix
Prefix string, e.g. "> ".
Definition qstyle.h:58
struct QuoteStyle * down
Parent (less quoted) and child (more quoted) levels.
Definition qstyle.h:61
int quote_n
The quoteN colour index for this level.
Definition qstyle.h:56
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 58 of file qstyle.c.

59{
60 struct QuoteStyle *next = NULL;
61
62 while (*quote_list)
63 {
64 if ((*quote_list)->down)
65 qstyle_free_tree(&((*quote_list)->down));
66 next = (*quote_list)->next;
67 qstyle_free(quote_list);
68 *quote_list = next;
69 }
70}
void qstyle_free_tree(struct QuoteStyle **quote_list)
Free an entire tree of QuoteStyle.
Definition qstyle.c:58
static void qstyle_free(struct QuoteStyle **ptr)
Free a single QuoteStyle object.
Definition qstyle.c:41
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 468 of file qstyle.c.

469{
470 if (!quote_list)
471 return;
472
473 int num = quoted_colors_num_used();
474 int cur = 0;
475
476 qstyle_recurse(quote_list, num, &cur);
477}
static void qstyle_recurse(struct QuoteStyle *quote_list, int num_qlevel, int *cur_qlevel)
Update the quoting styles after colour changes.
Definition qstyle.c:445
int quoted_colors_num_used(void)
Return the number of used quotes.
Definition quoted.c:118
Here is the call graph for this function:
Here is the caller graph for this function: