ascii-chat 0.8.38
Real-time terminal-based video chat with ASCII art conversion
Loading...
Searching...
No Matches
ansi.c
Go to the documentation of this file.
1
7#include <ascii-chat/video/ansi.h>
8#include <ascii-chat/video/output_buffer.h>
9#include <ascii-chat/common.h>
10
11#include <string.h>
12
13char *ansi_strip_escapes(const char *input, size_t input_len) {
14 if (!input || input_len == 0) {
15 return NULL;
16 }
17
18 // Output will be at most input_len (stripping only removes chars)
19 outbuf_t ob = {0};
20 ob_reserve(&ob, input_len);
21
22 size_t i = 0;
23 while (i < input_len) {
24 // Check for ESC character (start of ANSI sequence)
25 if (input[i] == '\x1b' && i + 1 < input_len && input[i + 1] == '[') {
26 // Skip ESC[
27 i += 2;
28
29 // Skip parameter bytes (digits, semicolons, and intermediate bytes)
30 while (i < input_len) {
31 char c = input[i];
32 // Parameter bytes: 0x30-0x3F (digits, semicolon, etc.)
33 // Intermediate bytes: 0x20-0x2F (space, !, ", etc.)
34 if ((c >= 0x30 && c <= 0x3F) || (c >= 0x20 && c <= 0x2F)) {
35 i++;
36 } else {
37 break;
38 }
39 }
40
41 // Skip final byte (0x40-0x7E: @, A-Z, [, \, ], ^, _, `, a-z, {, |, }, ~)
42 if (i < input_len) {
43 char final = input[i];
44 if (final >= 0x40 && final <= 0x7E) {
45 i++;
46 }
47 }
48 } else {
49 // Regular character - copy to output
50 ob_putc(&ob, input[i]);
51 i++;
52 }
53 }
54
55 ob_term(&ob);
56 return ob.buf;
57}
58
59bool ansi_is_already_colorized(const char *message, size_t pos) {
60 if (!message) {
61 return false;
62 }
63
64 bool in_reset = true; // Start in reset state
65
66 // Scan from beginning to current position looking for ANSI codes
67 for (size_t i = 0; i < pos && message[i] != '\0'; i++) {
68 if (message[i] == '\x1b' && message[i + 1] == '[') {
69 // Found ANSI escape sequence start
70 // Look for the end marker 'm'
71 size_t j = i + 2;
72 while (message[j] != '\0' && message[j] != 'm') {
73 j++;
74 }
75
76 if (message[j] == 'm') {
77 // Extract the color code part (between [ and m)
78 // Check if it's a reset code: \x1b[0m or \x1b[m
79 if ((j == i + 3 && message[i + 2] == '0') || (j == i + 2)) {
80 // Reset code
81 in_reset = true;
82 } else {
83 // Color code (anything else)
84 in_reset = false;
85 }
86 }
87 }
88 }
89
90 // Return true if NOT in reset state (already colorized)
91 return !in_reset;
92}
char * ansi_strip_escapes(const char *input, size_t input_len)
Definition ansi.c:13
bool ansi_is_already_colorized(const char *message, size_t pos)
Definition ansi.c:59
void ob_term(outbuf_t *ob)
void ob_putc(outbuf_t *ob, char c)
void ob_reserve(outbuf_t *ob, size_t need)