aboutsummaryrefslogtreecommitdiff
path: root/draw.c
blob: d6a032be1b1e7261585bdde73468b205cd66ac67 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <wchar.h>
#include "sayeth.h"

size_t START_Y_BOX = 0;
size_t START_Y_CARET = 0;
size_t START_Y_DATA = 0;
const wchar_t *A_TAB = L"    ";
wchar_t wspace = L' ';
wchar_t box_top_left = L'\0';
wchar_t box_top = L'\0';
wchar_t box_top_right = L'\0';
wchar_t box_side = L'\0';
wchar_t box_bottom_left = L'\0';
wchar_t box_bottom = L'\0';
wchar_t box_bottom_right = L'\0';
extern int do_fill;

void box_draw_top(size_t y, size_t longest) {
    repchar(wspace, y);
    repchar(box_top_left, 1);
    repchar(box_top, longest);
    repchar(box_top_right, 1);
}

void box_draw_bottom(size_t y, size_t longest) {
    repchar(wspace, y);
    repchar(box_bottom_left, 1);
    repchar(box_bottom, longest);
    repchar(box_bottom_right, 1);
}

void box_draw_next_line(size_t y) {
    repchar(wspace, y);
    repchar(box_side, 1);
}

void box_draw_end_line(size_t longest, size_t len) {
    repchar(wspace, longest - len);
    repchar(box_side, 1);
}

int box_printf(const wchar_t *fmt, ...) {
    int count;
    va_list list;
    va_start(list, fmt);
    size_t len = 0;
    wchar_t data[INPUT_BUFSIZ] = {0};
    wchar_t output[INPUT_BUFSIZ] = {0};
    count = vswprintf(data, sizeof(data) - 1, fmt, list);

    // convert tabs to spaces
    for (size_t i = 0, n = 0; i < wcslen(data) && n < sizeof(output); i++, n++) {
        if (data[i] == L'\t') {
            wcscat(&output[n], A_TAB);
            n = n + wcslen(A_TAB) - 1;
            continue;
        }
        output[n] = data[i];
    }

    size_t longest = get_longest_line(output);

    box_draw_top(START_Y_BOX, longest);
    wprintf(L"\n");

    for (size_t i = 0; i < wcslen(output); i++) {
        if (i == wcslen(output) - 1) {
            box_draw_end_line(longest, len);
            continue;
        }

        if (len == 0) {
            box_draw_next_line(START_Y_BOX);
        }

        if (output[i] == '\n') {
            box_draw_end_line(longest, len);
            putwc('\n', stdout);
            len = 0;
            continue;
        }

        putwc(output[i], stdout);

        len++;
    }
    wprintf(L"\n");
    box_draw_bottom(START_Y_BOX, longest);

    va_end(list);
    return count;
}

void caret_draw(wchar_t *data, size_t indent, size_t attached) {
    if (!wcslen(data))
        return;

    if (!attached)
        repchar(wspace, START_Y_BOX);

    for (size_t i = 0; i < wcslen(data); i++) {
        if (data[i] == L'\\' && isalpha(data[i + 1])) {
            i++;
            switch (data[i]) {
                case 'n':
                    putwc(L'\n', stdout);
                    if (i == wcslen(data) - 1)
                        continue;
                    repchar(wspace, indent);
                    continue;
                default:
                    continue;
            }
        }
        putwc(data[i], stdout);
    }
}

size_t count_lines(wchar_t *s) {
    size_t count = 0;
    wchar_t *ptr = s;

    while (*ptr != L'\0') {
        if (*ptr == L'\n')
            count++;
        ptr++;
    }
    return count;
}

void data_draw(wchar_t *data, size_t indent) {
    size_t len = 0;
    wchar_t *inbuf = wcsdup(data);
    size_t longest = get_longest_line(inbuf);
    size_t lines = count_lines(inbuf);
    wchar_t buf[DATA_BUFSIZ] = {0};

    wchar_t *token = NULL;
    wchar_t *ptr;
    token = wcstok(inbuf, L"\n", &ptr);
    for (size_t i = 0; token != NULL; i++) {
        memset(buf, '\0', sizeof(buf));
        for (size_t y = 0; y < indent; y++) {
            buf[y] = wspace;
        }
        wcscat(buf, token);
        len = wcslen(buf);
        if (i < lines) {
            for (size_t y = len; y < longest + (indent * 2); y++) {
                buf[y] = wspace;
            }
            wcscat(buf, L"\n");
        }
        wprintf(L"%S", buf);
        token = wcstok(NULL, L"\n", &ptr);
    }
}