lipgloss 0.1.0-x86-linux-musl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ #ifndef LIPGLOSS_EXTENSION_H
2
+ #define LIPGLOSS_EXTENSION_H
3
+
4
+ #include <ruby.h>
5
+ #include "liblipgloss.h"
6
+
7
+ extern VALUE mLipgloss;
8
+ extern VALUE cStyle;
9
+ extern VALUE cTable;
10
+ extern VALUE cList;
11
+ extern VALUE cTree;
12
+
13
+ extern const rb_data_type_t style_type;
14
+ extern const rb_data_type_t table_type;
15
+ extern const rb_data_type_t list_type;
16
+ extern const rb_data_type_t tree_type;
17
+
18
+ typedef struct {
19
+ unsigned long long handle;
20
+ } lipgloss_style_t;
21
+
22
+ typedef struct {
23
+ unsigned long long handle;
24
+ } lipgloss_table_t;
25
+
26
+ typedef struct {
27
+ unsigned long long handle;
28
+ } lipgloss_list_t;
29
+
30
+ typedef struct {
31
+ unsigned long long handle;
32
+ } lipgloss_tree_t;
33
+
34
+
35
+ #define GET_STYLE(self, style) \
36
+ lipgloss_style_t *style; \
37
+ TypedData_Get_Struct(self, lipgloss_style_t, &style_type, style)
38
+
39
+ #define GET_TABLE(self, table) \
40
+ lipgloss_table_t *table; \
41
+ TypedData_Get_Struct(self, lipgloss_table_t, &table_type, table)
42
+
43
+ #define GET_LIST(self, list) \
44
+ lipgloss_list_t *list; \
45
+ TypedData_Get_Struct(self, lipgloss_list_t, &list_type, list)
46
+
47
+ #define GET_TREE(self, tree) \
48
+ lipgloss_tree_t *tree; \
49
+ TypedData_Get_Struct(self, lipgloss_tree_t, &tree_type, tree)
50
+
51
+ #define BORDER_NORMAL 0
52
+ #define BORDER_ROUNDED 1
53
+ #define BORDER_THICK 2
54
+ #define BORDER_DOUBLE 3
55
+ #define BORDER_HIDDEN 4
56
+ #define BORDER_BLOCK 5
57
+ #define BORDER_OUTER_HALF_BLOCK 6
58
+ #define BORDER_INNER_HALF_BLOCK 7
59
+ #define BORDER_ASCII 8
60
+ #define BORDER_MARKDOWN 9
61
+
62
+ VALUE style_wrap(VALUE klass, unsigned long long handle);
63
+ VALUE table_wrap(VALUE klass, unsigned long long handle);
64
+ VALUE list_wrap_handle(VALUE klass, unsigned long long handle);
65
+ VALUE tree_wrap_handle(VALUE klass, unsigned long long handle);
66
+
67
+ void Init_lipgloss_style(void);
68
+ void Init_lipgloss_table(void);
69
+ void Init_lipgloss_list(void);
70
+ void Init_lipgloss_tree(void);
71
+
72
+ void register_style_spacing_methods(void);
73
+ void register_style_border_methods(void);
74
+ void register_style_unset_methods(void);
75
+
76
+ #endif
@@ -0,0 +1,147 @@
1
+ #include "extension.h"
2
+
3
+ static void list_free(void *pointer) {
4
+ lipgloss_list_t *list = (lipgloss_list_t *) pointer;
5
+
6
+ if (list->handle != 0) {
7
+ lipgloss_list_free(list->handle);
8
+ }
9
+
10
+ xfree(list);
11
+ }
12
+
13
+ static size_t list_memsize(const void *pointer) {
14
+ return sizeof(lipgloss_list_t);
15
+ }
16
+
17
+ const rb_data_type_t list_type = {
18
+ .wrap_struct_name = "Lipgloss::List",
19
+ .function = {
20
+ .dmark = NULL,
21
+ .dfree = list_free,
22
+ .dsize = list_memsize,
23
+ },
24
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
25
+ };
26
+
27
+ static VALUE list_alloc(VALUE klass) {
28
+ lipgloss_list_t *list = ALLOC(lipgloss_list_t);
29
+ list->handle = lipgloss_list_new();
30
+
31
+ return TypedData_Wrap_Struct(klass, &list_type, list);
32
+ }
33
+
34
+ VALUE list_wrap_handle(VALUE klass, unsigned long long handle) {
35
+ lipgloss_list_t *list = ALLOC(lipgloss_list_t);
36
+ list->handle = handle;
37
+
38
+ return TypedData_Wrap_Struct(klass, &list_type, list);
39
+ }
40
+
41
+ static VALUE list_initialize(int argc, VALUE *argv, VALUE self) {
42
+ if (argc > 0) {
43
+ GET_LIST(self, list);
44
+ VALUE json_str = rb_funcall(rb_ary_new_from_values(argc, argv), rb_intern("to_json"), 0);
45
+ list->handle = lipgloss_list_items(list->handle, StringValueCStr(json_str));
46
+ }
47
+
48
+ return self;
49
+ }
50
+
51
+ static VALUE list_item(VALUE self, VALUE item) {
52
+ GET_LIST(self, list);
53
+
54
+ if (rb_obj_is_kind_of(item, cList)) {
55
+ lipgloss_list_t *sublist;
56
+ TypedData_Get_Struct(item, lipgloss_list_t, &list_type, sublist);
57
+ unsigned long long new_handle = lipgloss_list_item_list(list->handle, sublist->handle);
58
+
59
+ return list_wrap_handle(rb_class_of(self), new_handle);
60
+ }
61
+
62
+ Check_Type(item, T_STRING);
63
+ unsigned long long new_handle = lipgloss_list_item(list->handle, StringValueCStr(item));
64
+
65
+ return list_wrap_handle(rb_class_of(self), new_handle);
66
+ }
67
+
68
+ static VALUE list_items(VALUE self, VALUE items) {
69
+ GET_LIST(self, list);
70
+ Check_Type(items, T_ARRAY);
71
+
72
+ VALUE json_str = rb_funcall(items, rb_intern("to_json"), 0);
73
+ unsigned long long new_handle = lipgloss_list_items(list->handle, StringValueCStr(json_str));
74
+
75
+ return list_wrap_handle(rb_class_of(self), new_handle);
76
+ }
77
+
78
+ #define LIST_ENUMERATOR_BULLET 0
79
+ #define LIST_ENUMERATOR_ARABIC 1
80
+ #define LIST_ENUMERATOR_ALPHABET 2
81
+ #define LIST_ENUMERATOR_ROMAN 3
82
+ #define LIST_ENUMERATOR_DASH 4
83
+ #define LIST_ENUMERATOR_ASTERISK 5
84
+
85
+ static int symbol_to_list_enumerator(VALUE symbol) {
86
+ if (symbol == ID2SYM(rb_intern("bullet"))) return LIST_ENUMERATOR_BULLET;
87
+ if (symbol == ID2SYM(rb_intern("arabic"))) return LIST_ENUMERATOR_ARABIC;
88
+ if (symbol == ID2SYM(rb_intern("alphabet"))) return LIST_ENUMERATOR_ALPHABET;
89
+ if (symbol == ID2SYM(rb_intern("roman"))) return LIST_ENUMERATOR_ROMAN;
90
+ if (symbol == ID2SYM(rb_intern("dash"))) return LIST_ENUMERATOR_DASH;
91
+ if (symbol == ID2SYM(rb_intern("asterisk"))) return LIST_ENUMERATOR_ASTERISK;
92
+
93
+ return LIST_ENUMERATOR_BULLET;
94
+ }
95
+
96
+ static VALUE list_enumerator(VALUE self, VALUE enum_symbol) {
97
+ GET_LIST(self, list);
98
+ int enum_type = symbol_to_list_enumerator(enum_symbol);
99
+ unsigned long long new_handle = lipgloss_list_enumerator(list->handle, enum_type);
100
+
101
+ return list_wrap_handle(rb_class_of(self), new_handle);
102
+ }
103
+
104
+ static VALUE list_enumerator_style(VALUE self, VALUE style_object) {
105
+ GET_LIST(self, list);
106
+ lipgloss_style_t *style;
107
+
108
+ TypedData_Get_Struct(style_object, lipgloss_style_t, &style_type, style);
109
+ unsigned long long new_handle = lipgloss_list_enumerator_style(list->handle, style->handle);
110
+
111
+ return list_wrap_handle(rb_class_of(self), new_handle);
112
+ }
113
+
114
+ static VALUE list_item_style(VALUE self, VALUE style_object) {
115
+ GET_LIST(self, list);
116
+ lipgloss_style_t *style;
117
+ TypedData_Get_Struct(style_object, lipgloss_style_t, &style_type, style);
118
+ unsigned long long new_handle = lipgloss_list_item_style(list->handle, style->handle);
119
+ return list_wrap_handle(rb_class_of(self), new_handle);
120
+ }
121
+
122
+ static VALUE list_render(VALUE self) {
123
+ GET_LIST(self, list);
124
+ char *result = lipgloss_list_render(list->handle);
125
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
126
+ lipgloss_free(result);
127
+ return rb_result;
128
+ }
129
+
130
+ static VALUE list_to_s(VALUE self) {
131
+ return list_render(self);
132
+ }
133
+
134
+ void Init_lipgloss_list(void) {
135
+ cList = rb_define_class_under(mLipgloss, "List", rb_cObject);
136
+
137
+ rb_define_alloc_func(cList, list_alloc);
138
+
139
+ rb_define_method(cList, "initialize", list_initialize, -1);
140
+ rb_define_method(cList, "item", list_item, 1);
141
+ rb_define_method(cList, "items", list_items, 1);
142
+ rb_define_method(cList, "enumerator", list_enumerator, 1);
143
+ rb_define_method(cList, "enumerator_style", list_enumerator_style, 1);
144
+ rb_define_method(cList, "item_style", list_item_style, 1);
145
+ rb_define_method(cList, "render", list_render, 0);
146
+ rb_define_method(cList, "to_s", list_to_s, 0);
147
+ }
@@ -0,0 +1,398 @@
1
+ #include "extension.h"
2
+
3
+ static void style_free(void *pointer) {
4
+ lipgloss_style_t *style = (lipgloss_style_t *) pointer;
5
+
6
+ if (style->handle != 0) {
7
+ lipgloss_free_style(style->handle);
8
+ }
9
+
10
+ xfree(style);
11
+ }
12
+
13
+ static size_t style_memsize(const void *pointer) {
14
+ return sizeof(lipgloss_style_t);
15
+ }
16
+
17
+ const rb_data_type_t style_type = {
18
+ .wrap_struct_name = "Lipgloss::Style",
19
+ .function = {
20
+ .dmark = NULL,
21
+ .dfree = style_free,
22
+ .dsize = style_memsize,
23
+ },
24
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY
25
+ };
26
+
27
+ static VALUE style_alloc(VALUE klass) {
28
+ lipgloss_style_t *style = ALLOC(lipgloss_style_t);
29
+ style->handle = lipgloss_new_style();
30
+ return TypedData_Wrap_Struct(klass, &style_type, style);
31
+ }
32
+
33
+ VALUE style_wrap(VALUE klass, unsigned long long handle) {
34
+ lipgloss_style_t *style = ALLOC(lipgloss_style_t);
35
+
36
+ style->handle = handle;
37
+
38
+ return TypedData_Wrap_Struct(klass, &style_type, style);
39
+ }
40
+
41
+ static VALUE style_initialize(VALUE self) {
42
+ return self;
43
+ }
44
+
45
+ static VALUE style_render(VALUE self, VALUE string) {
46
+ GET_STYLE(self, style);
47
+ Check_Type(string, T_STRING);
48
+
49
+ char *result = lipgloss_style_render(style->handle, StringValueCStr(string));
50
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
51
+ lipgloss_free(result);
52
+
53
+ return rb_result;
54
+ }
55
+
56
+ // Formatting methods
57
+
58
+ static VALUE style_bold(VALUE self, VALUE value) {
59
+ GET_STYLE(self, style);
60
+ unsigned long long new_handle = lipgloss_style_bold(style->handle, RTEST(value) ? 1 : 0);
61
+ return style_wrap(rb_class_of(self), new_handle);
62
+ }
63
+
64
+ static VALUE style_italic(VALUE self, VALUE value) {
65
+ GET_STYLE(self, style);
66
+ unsigned long long new_handle = lipgloss_style_italic(style->handle, RTEST(value) ? 1 : 0);
67
+ return style_wrap(rb_class_of(self), new_handle);
68
+ }
69
+
70
+ static VALUE style_underline(VALUE self, VALUE value) {
71
+ GET_STYLE(self, style);
72
+ unsigned long long new_handle = lipgloss_style_underline(style->handle, RTEST(value) ? 1 : 0);
73
+ return style_wrap(rb_class_of(self), new_handle);
74
+ }
75
+
76
+ static VALUE style_strikethrough(VALUE self, VALUE value) {
77
+ GET_STYLE(self, style);
78
+ unsigned long long new_handle = lipgloss_style_strikethrough(style->handle, RTEST(value) ? 1 : 0);
79
+ return style_wrap(rb_class_of(self), new_handle);
80
+ }
81
+
82
+ static VALUE style_reverse(VALUE self, VALUE value) {
83
+ GET_STYLE(self, style);
84
+ unsigned long long new_handle = lipgloss_style_reverse(style->handle, RTEST(value) ? 1 : 0);
85
+ return style_wrap(rb_class_of(self), new_handle);
86
+ }
87
+
88
+ static VALUE style_blink(VALUE self, VALUE value) {
89
+ GET_STYLE(self, style);
90
+ unsigned long long new_handle = lipgloss_style_blink(style->handle, RTEST(value) ? 1 : 0);
91
+ return style_wrap(rb_class_of(self), new_handle);
92
+ }
93
+
94
+ static VALUE style_faint(VALUE self, VALUE value) {
95
+ GET_STYLE(self, style);
96
+ unsigned long long new_handle = lipgloss_style_faint(style->handle, RTEST(value) ? 1 : 0);
97
+ return style_wrap(rb_class_of(self), new_handle);
98
+ }
99
+
100
+ // Color helper functions
101
+
102
+ static int is_complete_color(VALUE obj) {
103
+ return rb_respond_to(obj, rb_intern("true_color")) && rb_respond_to(obj, rb_intern("ansi256")) && rb_respond_to(obj, rb_intern("ansi"));
104
+ }
105
+
106
+ static int is_adaptive_color(VALUE obj) {
107
+ return rb_respond_to(obj, rb_intern("light")) && rb_respond_to(obj, rb_intern("dark"));
108
+ }
109
+
110
+ // Color methods
111
+
112
+ static VALUE style_foreground(VALUE self, VALUE color) {
113
+ GET_STYLE(self, style);
114
+
115
+ if (is_adaptive_color(color)) {
116
+ VALUE light = rb_funcall(color, rb_intern("light"), 0);
117
+ VALUE dark = rb_funcall(color, rb_intern("dark"), 0);
118
+
119
+ if (is_complete_color(light) && is_complete_color(dark)) {
120
+ VALUE light_true = rb_funcall(light, rb_intern("true_color"), 0);
121
+ VALUE light_256 = rb_funcall(light, rb_intern("ansi256"), 0);
122
+ VALUE light_ansi = rb_funcall(light, rb_intern("ansi"), 0);
123
+ VALUE dark_true = rb_funcall(dark, rb_intern("true_color"), 0);
124
+ VALUE dark_256 = rb_funcall(dark, rb_intern("ansi256"), 0);
125
+ VALUE dark_ansi = rb_funcall(dark, rb_intern("ansi"), 0);
126
+
127
+ unsigned long long new_handle = lipgloss_style_foreground_complete_adaptive(
128
+ style->handle,
129
+ StringValueCStr(light_true),
130
+ StringValueCStr(light_256),
131
+ StringValueCStr(light_ansi),
132
+ StringValueCStr(dark_true),
133
+ StringValueCStr(dark_256),
134
+ StringValueCStr(dark_ansi)
135
+ );
136
+
137
+ return style_wrap(rb_class_of(self), new_handle);
138
+ }
139
+
140
+ unsigned long long new_handle = lipgloss_style_foreground_adaptive(
141
+ style->handle,
142
+ StringValueCStr(light),
143
+ StringValueCStr(dark)
144
+ );
145
+
146
+ return style_wrap(rb_class_of(self), new_handle);
147
+ }
148
+
149
+ if (is_complete_color(color)) {
150
+ VALUE true_color = rb_funcall(color, rb_intern("true_color"), 0);
151
+ VALUE ansi256 = rb_funcall(color, rb_intern("ansi256"), 0);
152
+ VALUE ansi = rb_funcall(color, rb_intern("ansi"), 0);
153
+
154
+ unsigned long long new_handle = lipgloss_style_foreground_complete(
155
+ style->handle,
156
+ StringValueCStr(true_color),
157
+ StringValueCStr(ansi256),
158
+ StringValueCStr(ansi)
159
+ );
160
+
161
+ return style_wrap(rb_class_of(self), new_handle);
162
+ }
163
+
164
+ Check_Type(color, T_STRING);
165
+ unsigned long long new_handle = lipgloss_style_foreground(style->handle, StringValueCStr(color));
166
+
167
+ return style_wrap(rb_class_of(self), new_handle);
168
+ }
169
+
170
+ static VALUE style_background(VALUE self, VALUE color) {
171
+ GET_STYLE(self, style);
172
+
173
+ if (is_adaptive_color(color)) {
174
+ VALUE light = rb_funcall(color, rb_intern("light"), 0);
175
+ VALUE dark = rb_funcall(color, rb_intern("dark"), 0);
176
+
177
+ if (is_complete_color(light) && is_complete_color(dark)) {
178
+ VALUE light_true = rb_funcall(light, rb_intern("true_color"), 0);
179
+ VALUE light_256 = rb_funcall(light, rb_intern("ansi256"), 0);
180
+ VALUE light_ansi = rb_funcall(light, rb_intern("ansi"), 0);
181
+ VALUE dark_true = rb_funcall(dark, rb_intern("true_color"), 0);
182
+ VALUE dark_256 = rb_funcall(dark, rb_intern("ansi256"), 0);
183
+ VALUE dark_ansi = rb_funcall(dark, rb_intern("ansi"), 0);
184
+
185
+ unsigned long long new_handle = lipgloss_style_background_complete_adaptive(
186
+ style->handle,
187
+ StringValueCStr(light_true),
188
+ StringValueCStr(light_256),
189
+ StringValueCStr(light_ansi),
190
+ StringValueCStr(dark_true),
191
+ StringValueCStr(dark_256),
192
+ StringValueCStr(dark_ansi)
193
+ );
194
+
195
+ return style_wrap(rb_class_of(self), new_handle);
196
+ }
197
+
198
+ unsigned long long new_handle = lipgloss_style_background_adaptive(
199
+ style->handle,
200
+ StringValueCStr(light),
201
+ StringValueCStr(dark)
202
+ );
203
+
204
+ return style_wrap(rb_class_of(self), new_handle);
205
+ }
206
+
207
+ if (is_complete_color(color)) {
208
+ VALUE true_color = rb_funcall(color, rb_intern("true_color"), 0);
209
+ VALUE ansi256 = rb_funcall(color, rb_intern("ansi256"), 0);
210
+ VALUE ansi = rb_funcall(color, rb_intern("ansi"), 0);
211
+
212
+ unsigned long long new_handle = lipgloss_style_background_complete(
213
+ style->handle,
214
+ StringValueCStr(true_color),
215
+ StringValueCStr(ansi256),
216
+ StringValueCStr(ansi)
217
+ );
218
+
219
+ return style_wrap(rb_class_of(self), new_handle);
220
+ }
221
+
222
+ Check_Type(color, T_STRING);
223
+ unsigned long long new_handle = lipgloss_style_background(style->handle, StringValueCStr(color));
224
+
225
+ return style_wrap(rb_class_of(self), new_handle);
226
+ }
227
+
228
+ static VALUE style_margin_background(VALUE self, VALUE color) {
229
+ GET_STYLE(self, style);
230
+ Check_Type(color, T_STRING);
231
+
232
+ unsigned long long new_handle = lipgloss_style_margin_background(style->handle, StringValueCStr(color));
233
+
234
+ return style_wrap(rb_class_of(self), new_handle);
235
+ }
236
+
237
+ // Size methods
238
+
239
+ static VALUE style_width(VALUE self, VALUE width) {
240
+ GET_STYLE(self, style);
241
+ unsigned long long new_handle = lipgloss_style_width(style->handle, NUM2INT(width));
242
+ return style_wrap(rb_class_of(self), new_handle);
243
+ }
244
+
245
+ static VALUE style_height(VALUE self, VALUE height) {
246
+ GET_STYLE(self, style);
247
+ unsigned long long new_handle = lipgloss_style_height(style->handle, NUM2INT(height));
248
+ return style_wrap(rb_class_of(self), new_handle);
249
+ }
250
+
251
+ static VALUE style_max_width(VALUE self, VALUE width) {
252
+ GET_STYLE(self, style);
253
+ unsigned long long new_handle = lipgloss_style_max_width(style->handle, NUM2INT(width));
254
+ return style_wrap(rb_class_of(self), new_handle);
255
+ }
256
+
257
+ static VALUE style_max_height(VALUE self, VALUE height) {
258
+ GET_STYLE(self, style);
259
+ unsigned long long new_handle = lipgloss_style_max_height(style->handle, NUM2INT(height));
260
+ return style_wrap(rb_class_of(self), new_handle);
261
+ }
262
+
263
+ // Alignment methods
264
+
265
+ static VALUE style_align(int argc, VALUE *argv, VALUE self) {
266
+ GET_STYLE(self, style);
267
+
268
+ if (argc == 0 || argc > 2) {
269
+ rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 1..2)", argc);
270
+ }
271
+
272
+ double positions[2];
273
+ for (int index = 0; index < argc; index++) {
274
+ positions[index] = NUM2DBL(argv[index]);
275
+ }
276
+
277
+ unsigned long long new_handle = lipgloss_style_align(style->handle, positions, argc);
278
+
279
+ return style_wrap(rb_class_of(self), new_handle);
280
+ }
281
+
282
+ static VALUE style_align_horizontal(VALUE self, VALUE position) {
283
+ GET_STYLE(self, style);
284
+ unsigned long long new_handle = lipgloss_style_align_horizontal(style->handle, NUM2DBL(position));
285
+ return style_wrap(rb_class_of(self), new_handle);
286
+ }
287
+
288
+ static VALUE style_align_vertical(VALUE self, VALUE position) {
289
+ GET_STYLE(self, style);
290
+ unsigned long long new_handle = lipgloss_style_align_vertical(style->handle, NUM2DBL(position));
291
+ return style_wrap(rb_class_of(self), new_handle);
292
+ }
293
+
294
+ // Other style methods
295
+
296
+ static VALUE style_inline(VALUE self, VALUE value) {
297
+ GET_STYLE(self, style);
298
+ unsigned long long new_handle = lipgloss_style_inline(style->handle, RTEST(value) ? 1 : 0);
299
+ return style_wrap(rb_class_of(self), new_handle);
300
+ }
301
+
302
+ static VALUE style_tab_width(VALUE self, VALUE width) {
303
+ GET_STYLE(self, style);
304
+ unsigned long long new_handle = lipgloss_style_tab_width(style->handle, NUM2INT(width));
305
+ return style_wrap(rb_class_of(self), new_handle);
306
+ }
307
+
308
+ static VALUE style_underline_spaces(VALUE self, VALUE value) {
309
+ GET_STYLE(self, style);
310
+ unsigned long long new_handle = lipgloss_style_underline_spaces(style->handle, RTEST(value) ? 1 : 0);
311
+ return style_wrap(rb_class_of(self), new_handle);
312
+ }
313
+
314
+ static VALUE style_strikethrough_spaces(VALUE self, VALUE value) {
315
+ GET_STYLE(self, style);
316
+ unsigned long long new_handle = lipgloss_style_strikethrough_spaces(style->handle, RTEST(value) ? 1 : 0);
317
+ return style_wrap(rb_class_of(self), new_handle);
318
+ }
319
+
320
+ // SetString, Inherit, to_s
321
+
322
+ static VALUE style_set_string(VALUE self, VALUE string) {
323
+ GET_STYLE(self, style);
324
+ Check_Type(string, T_STRING);
325
+
326
+ unsigned long long new_handle = lipgloss_style_set_string(style->handle, StringValueCStr(string));
327
+
328
+ return style_wrap(rb_class_of(self), new_handle);
329
+ }
330
+
331
+ static VALUE style_inherit(VALUE self, VALUE other) {
332
+ GET_STYLE(self, style);
333
+ lipgloss_style_t *other_style;
334
+
335
+ TypedData_Get_Struct(other, lipgloss_style_t, &style_type, other_style);
336
+ unsigned long long new_handle = lipgloss_style_inherit(style->handle, other_style->handle);
337
+
338
+ return style_wrap(rb_class_of(self), new_handle);
339
+ }
340
+
341
+ static VALUE style_to_s(VALUE self) {
342
+ GET_STYLE(self, style);
343
+ char *result = lipgloss_style_string(style->handle);
344
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
345
+
346
+ lipgloss_free(result);
347
+
348
+ return rb_result;
349
+ }
350
+
351
+ void Init_lipgloss_style(void) {
352
+ cStyle = rb_define_class_under(mLipgloss, "Style", rb_cObject);
353
+
354
+ rb_define_alloc_func(cStyle, style_alloc);
355
+
356
+ rb_define_method(cStyle, "initialize", style_initialize, 0);
357
+ rb_define_method(cStyle, "render", style_render, 1);
358
+
359
+ // Formatting
360
+ rb_define_method(cStyle, "bold", style_bold, 1);
361
+ rb_define_method(cStyle, "italic", style_italic, 1);
362
+ rb_define_method(cStyle, "underline", style_underline, 1);
363
+ rb_define_method(cStyle, "strikethrough", style_strikethrough, 1);
364
+ rb_define_method(cStyle, "reverse", style_reverse, 1);
365
+ rb_define_method(cStyle, "blink", style_blink, 1);
366
+ rb_define_method(cStyle, "faint", style_faint, 1);
367
+
368
+ // Colors
369
+ rb_define_method(cStyle, "foreground", style_foreground, 1);
370
+ rb_define_method(cStyle, "background", style_background, 1);
371
+ rb_define_method(cStyle, "margin_background", style_margin_background, 1);
372
+
373
+ // Size
374
+ rb_define_method(cStyle, "width", style_width, 1);
375
+ rb_define_method(cStyle, "height", style_height, 1);
376
+ rb_define_method(cStyle, "max_width", style_max_width, 1);
377
+ rb_define_method(cStyle, "max_height", style_max_height, 1);
378
+
379
+ // Alignment
380
+ rb_define_method(cStyle, "align", style_align, -1);
381
+ rb_define_method(cStyle, "align_horizontal", style_align_horizontal, 1);
382
+ rb_define_method(cStyle, "align_vertical", style_align_vertical, 1);
383
+
384
+ // Other
385
+ rb_define_method(cStyle, "inline", style_inline, 1);
386
+ rb_define_method(cStyle, "tab_width", style_tab_width, 1);
387
+ rb_define_method(cStyle, "underline_spaces", style_underline_spaces, 1);
388
+ rb_define_method(cStyle, "strikethrough_spaces", style_strikethrough_spaces, 1);
389
+
390
+ rb_define_method(cStyle, "set_string", style_set_string, 1);
391
+ rb_define_method(cStyle, "inherit", style_inherit, 1);
392
+ rb_define_method(cStyle, "to_s", style_to_s, 0);
393
+
394
+ // Register methods from sub-files
395
+ register_style_spacing_methods();
396
+ register_style_border_methods();
397
+ register_style_unset_methods();
398
+ }