NeoMutt  2024-12-12-14-g7b49f7
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
qstyle.h File Reference

Quoted style. More...

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

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