lipgloss 0.1.0-x86_64-darwin → 0.2.0-x86_64-darwin

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1414c1917d03cc49ef4a0b6372617ce75fda40155ef30253415154fe2187f86
4
- data.tar.gz: 40f31400e2f658ab68e7b1645ab5299e1f519e44d563286828af84828a606509
3
+ metadata.gz: 9ea95944023884864feb4b5e709264b23129b69357017288ea89f1994bbc7d53
4
+ data.tar.gz: 484b930da4da98dec979a6c17cfd690fa81f4c7aa29a172893c1aabbca3d2fa1
5
5
  SHA512:
6
- metadata.gz: ce3a7a0337cbe26a6651320ee5d069cfbcb6a83359250bcf6cde176f3035093184b4231d06529408eb7fa0873565e720e260143f0666e6fc0cff647613bc92c3
7
- data.tar.gz: 37995d8056f77ad2a10c9b3eb561acc1ff0a2ce53bf14acee137d20fe12b261e6a72c80205db5a848d8a2e047e73de29335cc4eb19d06bd6214d9725d88631c3
6
+ metadata.gz: 847c4ab8d6f03fc4070b243270bbb63352d14ae38b1788fb1a137e30d2735635534acaeed9d8e1af4c95eb7a50f1051a1c31a0f10f3af72b05a2ad031b98e74e
7
+ data.tar.gz: fe28d93bcfde1ffe19b0808788710fd5036f7991e1b790d0cf8e0c0f142b533adccbde99713dbfb94ee602ec2406a65f21f5ca510be4d7a27c9046e7d69f4980
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  <div align="center">
2
2
  <h1>Lipgloss for Ruby</h1>
3
- <h4>CSS-like Terminal Styling for Ruby CLI Apps</h4>
3
+ <h4>Style Definitions for Nice Terminal Layouts</h4>
4
4
 
5
5
  <p>
6
6
  <a href="https://rubygems.org/gems/lipgloss"><img alt="Gem Version" src="https://img.shields.io/gem/v/lipgloss"></a>
7
7
  <a href="https://github.com/marcoroth/lipgloss-ruby/blob/main/LICENSE.txt"><img alt="License" src="https://img.shields.io/github/license/marcoroth/lipgloss-ruby"></a>
8
8
  </p>
9
9
 
10
- <p>Ruby bindings for <a href="https://github.com/charmbracelet/lipgloss">charmbracelet/lipgloss</a>.<br/>Style definitions for nice terminal layouts with a fluent, CSS-like API.</p>
10
+ <p>Ruby bindings for <a href="https://github.com/charmbracelet/lipgloss">charmbracelet/lipgloss</a>.<br/>Style definitions for nice terminal layouts. Built with TUIs in mind.</p>
11
11
  </div>
12
12
 
13
13
  ## Installation
@@ -52,7 +52,7 @@ heading = Lipgloss::Style.new
52
52
 
53
53
  body = Lipgloss::Style.new
54
54
  .width(40)
55
- .align(Lipgloss::CENTER)
55
+ .align(:center)
56
56
 
57
57
  puts heading.render("Welcome")
58
58
  puts body.render("Styled terminal output")
@@ -118,21 +118,23 @@ puts style.render("Rainbow border!")
118
118
  left = box.render("Left")
119
119
  right = box.render("Right")
120
120
 
121
- puts Lipgloss.join_horizontal(Lipgloss::TOP, [left, right])
121
+ puts Lipgloss.join_horizontal(:top, left, right)
122
122
  ```
123
123
 
124
124
  **Join content vertically:**
125
125
 
126
126
  ```ruby
127
- puts Lipgloss.join_vertical(Lipgloss::CENTER, [left, right])
127
+ puts Lipgloss.join_vertical(:center, left, right)
128
128
  ```
129
129
 
130
130
  **Place content in whitespace:**
131
131
 
132
132
  ```ruby
133
- puts Lipgloss.place(40, 10, Lipgloss::CENTER, Lipgloss::CENTER, "Centered")
133
+ puts Lipgloss.place(40, 10, :center, :center, "Centered")
134
134
  ```
135
135
 
136
+ **Position symbols:** `:top`, `:bottom`, `:left`, `:right`, `:center` (or numeric 0.0-1.0)
137
+
136
138
  ### Colors
137
139
 
138
140
  **Simple hex colors:**
@@ -155,18 +157,20 @@ style = Lipgloss::Style.new
155
157
  ```ruby
156
158
  color = Lipgloss::CompleteColor.new(
157
159
  true_color: "#FF6B6B", # 24-bit color
158
- ansi256: "196", # 256-color fallback
159
- ansi: "9" # 16-color fallback
160
+ ansi256: 196, # 256-color fallback (integer)
161
+ ansi: :bright_red # 16-color fallback (symbol)
160
162
  )
161
163
 
162
164
  style = Lipgloss::Style.new.foreground(color)
163
165
  ```
164
166
 
167
+ **ANSI color symbols:** `:black`, `:red`, `:green`, `:yellow`, `:blue`, `:magenta`, `:cyan`, `:white`, and bright variants (`:bright_red`, etc.)
168
+
165
169
  **Complete adaptive colors:**
166
170
 
167
171
  ```ruby
168
- light = Lipgloss::CompleteColor.new(true_color: "#000", ansi256: "0", ansi: "0")
169
- dark = Lipgloss::CompleteColor.new(true_color: "#FFF", ansi256: "15", ansi: "15")
172
+ light = Lipgloss::CompleteColor.new(true_color: "#000", ansi256: :black, ansi: :black)
173
+ dark = Lipgloss::CompleteColor.new(true_color: "#FFF", ansi256: :bright_white, ansi: :bright_white)
170
174
  color = Lipgloss::CompleteAdaptiveColor.new(light: light, dark: dark)
171
175
 
172
176
  style = Lipgloss::Style.new.foreground(color)
@@ -376,7 +380,7 @@ puts tree.render
376
380
  | `align_horizontal(position)` | Horizontal alignment |
377
381
  | `align_vertical(position)` | Vertical alignment |
378
382
 
379
- **Position constants:** `Lipgloss::TOP`, `Lipgloss::BOTTOM`, `Lipgloss::LEFT`, `Lipgloss::RIGHT`, `Lipgloss::CENTER`
383
+ **Position symbols:** `:top`, `:bottom`, `:left`, `:right`, `:center` (or numeric 0.0-1.0)
380
384
 
381
385
  ### Other
382
386
 
@@ -402,17 +406,41 @@ puts tree.render
402
406
 
403
407
  ## Module Methods
404
408
 
405
- | Method | Description |
406
- |---------------------------------------------------------------------------------|--------------------------|
407
- | `Lipgloss.join_horizontal(position, strings)` | Join strings horizontally |
408
- | `Lipgloss.join_vertical(position, strings)` | Join strings vertically |
409
- | `Lipgloss.width(string)` | Get rendered width |
410
- | `Lipgloss.height(string)` | Get rendered height |
411
- | `Lipgloss.size(string)` | Get `[width, height]` |
412
- | `Lipgloss.place(width, height, horizontal_position, vertical_position, string)` | Place in whitespace |
413
- | `Lipgloss.place_horizontal(width, position, string)` | Place horizontally |
414
- | `Lipgloss.place_vertical(height, position, string)` | Place vertically |
415
- | `Lipgloss.has_dark_background?` | Check terminal background |
409
+ | Method | Description |
410
+ |-----------------------------------------------------------|---------------------------|
411
+ | `Lipgloss.join_horizontal(position, *strings)` | Join strings horizontally |
412
+ | `Lipgloss.join_vertical(position, *strings)` | Join strings vertically |
413
+ | `Lipgloss.width(string)` | Get rendered width |
414
+ | `Lipgloss.height(string)` | Get rendered height |
415
+ | `Lipgloss.size(string)` | Get `[width, height]` |
416
+ | `Lipgloss.place(width, height, h_pos, v_pos, string)` | Place in whitespace |
417
+ | `Lipgloss.place_horizontal(width, position, string)` | Place horizontally |
418
+ | `Lipgloss.place_vertical(height, position, string)` | Place vertically |
419
+ | `Lipgloss.has_dark_background?` | Check terminal background |
420
+
421
+ ### Color Blending
422
+
423
+ | Method | Description |
424
+ |----------------------------------------------------------------|--------------------------------|
425
+ | `Lipgloss::ColorBlend.blend(c1, c2, t, mode:)` | Blend two colors (0.0-1.0) |
426
+ | `Lipgloss::ColorBlend.blends(c1, c2, steps, mode:)` | Generate color gradient array |
427
+ | `Lipgloss::ColorBlend.grid(c1, c2, c3, c4, x, y, mode:)` | Generate 2D color grid |
428
+
429
+ **Blend modes:** `:luv` (default, perceptually uniform), `:rgb`, `:hcl`
430
+
431
+ #### Generate a 5-color gradient
432
+
433
+ ```ruby
434
+ colors = Lipgloss::ColorBlend.blends("#FF0000", "#0000FF", 5)
435
+ # => ["#ff0000", "#c1007f", "#7a00c1", "#0000ff", ...]
436
+ ```
437
+
438
+ #### Blend two colors at 50%
439
+
440
+ ```ruby
441
+ mid = Lipgloss::ColorBlend.blend("#FF0000", "#00FF00", 0.5)
442
+ # => "#b5b500"
443
+ ```
416
444
 
417
445
  ## Development
418
446
 
@@ -443,6 +471,7 @@ bundle exec rake test
443
471
  ```bash
444
472
  ./demo/basic
445
473
  ./demo/colors
474
+ ./demo/layout
446
475
  ./demo/table
447
476
  ./demo/list
448
477
  ./demo/tree
@@ -0,0 +1,158 @@
1
+ #include "extension.h"
2
+
3
+ VALUE mColor;
4
+
5
+ #define BLEND_LUV 0
6
+ #define BLEND_RGB 1
7
+ #define BLEND_HCL 2
8
+
9
+ static int blend_mode_from_symbol(VALUE mode) {
10
+ if (NIL_P(mode)) {
11
+ return BLEND_LUV;
12
+ }
13
+
14
+ ID mode_id = SYM2ID(mode);
15
+
16
+ if (mode_id == rb_intern("luv")) {
17
+ return BLEND_LUV;
18
+ } else if (mode_id == rb_intern("rgb")) {
19
+ return BLEND_RGB;
20
+ } else if (mode_id == rb_intern("hcl")) {
21
+ return BLEND_HCL;
22
+ }
23
+
24
+ return BLEND_LUV;
25
+ }
26
+
27
+ static VALUE color_blend(int argc, VALUE *argv, VALUE self) {
28
+ VALUE c1, c2, t, opts;
29
+ rb_scan_args(argc, argv, "3:", &c1, &c2, &t, &opts);
30
+
31
+ Check_Type(c1, T_STRING);
32
+ Check_Type(c2, T_STRING);
33
+
34
+ VALUE mode = Qnil;
35
+ if (!NIL_P(opts)) {
36
+ mode = rb_hash_aref(opts, ID2SYM(rb_intern("mode")));
37
+ }
38
+
39
+ int blend_mode = blend_mode_from_symbol(mode);
40
+ char *result;
41
+
42
+ switch (blend_mode) {
43
+ case BLEND_RGB:
44
+ result = lipgloss_color_blend_rgb(StringValueCStr(c1), StringValueCStr(c2), NUM2DBL(t));
45
+ break;
46
+ case BLEND_HCL:
47
+ result = lipgloss_color_blend_hcl(StringValueCStr(c1), StringValueCStr(c2), NUM2DBL(t));
48
+ break;
49
+ default:
50
+ result = lipgloss_color_blend_luv(StringValueCStr(c1), StringValueCStr(c2), NUM2DBL(t));
51
+ break;
52
+ }
53
+
54
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
55
+ lipgloss_free(result);
56
+
57
+ return rb_result;
58
+ }
59
+
60
+ static VALUE color_blend_luv(VALUE self, VALUE c1, VALUE c2, VALUE t) {
61
+ Check_Type(c1, T_STRING);
62
+ Check_Type(c2, T_STRING);
63
+
64
+ char *result = lipgloss_color_blend_luv(StringValueCStr(c1), StringValueCStr(c2), NUM2DBL(t));
65
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
66
+ lipgloss_free(result);
67
+
68
+ return rb_result;
69
+ }
70
+
71
+ static VALUE color_blend_rgb(VALUE self, VALUE c1, VALUE c2, VALUE t) {
72
+ Check_Type(c1, T_STRING);
73
+ Check_Type(c2, T_STRING);
74
+
75
+ char *result = lipgloss_color_blend_rgb(StringValueCStr(c1), StringValueCStr(c2), NUM2DBL(t));
76
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
77
+ lipgloss_free(result);
78
+
79
+ return rb_result;
80
+ }
81
+
82
+ static VALUE color_blend_hcl(VALUE self, VALUE c1, VALUE c2, VALUE t) {
83
+ Check_Type(c1, T_STRING);
84
+ Check_Type(c2, T_STRING);
85
+
86
+ char *result = lipgloss_color_blend_hcl(StringValueCStr(c1), StringValueCStr(c2), NUM2DBL(t));
87
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
88
+ lipgloss_free(result);
89
+
90
+ return rb_result;
91
+ }
92
+
93
+ static VALUE color_blends(int argc, VALUE *argv, VALUE self) {
94
+ VALUE c1, c2, steps, opts;
95
+ rb_scan_args(argc, argv, "3:", &c1, &c2, &steps, &opts);
96
+
97
+ Check_Type(c1, T_STRING);
98
+ Check_Type(c2, T_STRING);
99
+
100
+ VALUE mode = Qnil;
101
+ if (!NIL_P(opts)) {
102
+ mode = rb_hash_aref(opts, ID2SYM(rb_intern("mode")));
103
+ }
104
+
105
+ int blend_mode = blend_mode_from_symbol(mode);
106
+ char *result = lipgloss_color_blends(StringValueCStr(c1), StringValueCStr(c2), NUM2INT(steps), blend_mode);
107
+ VALUE json_string = rb_utf8_str_new_cstr(result);
108
+ lipgloss_free(result);
109
+
110
+ return rb_funcall(rb_const_get(rb_cObject, rb_intern("JSON")), rb_intern("parse"), 1, json_string);
111
+ }
112
+
113
+ static VALUE color_grid(int argc, VALUE *argv, VALUE self) {
114
+ VALUE x0y0, x1y0, x0y1, x1y1, x_steps, y_steps, opts;
115
+ rb_scan_args(argc, argv, "6:", &x0y0, &x1y0, &x0y1, &x1y1, &x_steps, &y_steps, &opts);
116
+
117
+ Check_Type(x0y0, T_STRING);
118
+ Check_Type(x1y0, T_STRING);
119
+ Check_Type(x0y1, T_STRING);
120
+ Check_Type(x1y1, T_STRING);
121
+
122
+ VALUE mode = Qnil;
123
+ if (!NIL_P(opts)) {
124
+ mode = rb_hash_aref(opts, ID2SYM(rb_intern("mode")));
125
+ }
126
+
127
+ int blend_mode = blend_mode_from_symbol(mode);
128
+
129
+ char *result = lipgloss_color_grid(
130
+ StringValueCStr(x0y0),
131
+ StringValueCStr(x1y0),
132
+ StringValueCStr(x0y1),
133
+ StringValueCStr(x1y1),
134
+ NUM2INT(x_steps),
135
+ NUM2INT(y_steps),
136
+ blend_mode
137
+ );
138
+
139
+ VALUE json_string = rb_utf8_str_new_cstr(result);
140
+ lipgloss_free(result);
141
+
142
+ return rb_funcall(rb_const_get(rb_cObject, rb_intern("JSON")), rb_intern("parse"), 1, json_string);
143
+ }
144
+
145
+ void Init_lipgloss_color(void) {
146
+ VALUE mColorBlend = rb_define_module_under(mLipgloss, "ColorBlend");
147
+
148
+ rb_define_singleton_method(mColorBlend, "blend", color_blend, -1);
149
+ rb_define_singleton_method(mColorBlend, "blend_luv", color_blend_luv, 3);
150
+ rb_define_singleton_method(mColorBlend, "blend_rgb", color_blend_rgb, 3);
151
+ rb_define_singleton_method(mColorBlend, "blend_hcl", color_blend_hcl, 3);
152
+ rb_define_singleton_method(mColorBlend, "blends", color_blends, -1);
153
+ rb_define_singleton_method(mColorBlend, "grid", color_grid, -1);
154
+
155
+ rb_define_const(mColorBlend, "LUV", ID2SYM(rb_intern("luv")));
156
+ rb_define_const(mColorBlend, "RGB", ID2SYM(rb_intern("rgb")));
157
+ rb_define_const(mColorBlend, "HCL", ID2SYM(rb_intern("hcl")));
158
+ }
@@ -56,6 +56,16 @@ when /linux/
56
56
  $LDFLAGS << " -lresolv" if find_library("resolv", "res_query")
57
57
  end
58
58
 
59
- $srcs = ["extension.c", "style.c", "style_spacing.c", "style_border.c", "style_unset.c", "table.c", "list.c", "tree.c"]
59
+ $srcs = [
60
+ "color.c",
61
+ "extension.c",
62
+ "list.c",
63
+ "style_border.c",
64
+ "style_spacing.c",
65
+ "style_unset.c",
66
+ "style.c",
67
+ "table.c",
68
+ "tree.c"
69
+ ]
60
70
 
61
71
  create_makefile("#{extension_name}/#{extension_name}")
@@ -6,11 +6,15 @@ VALUE cTable;
6
6
  VALUE cList;
7
7
  VALUE cTree;
8
8
 
9
+ int is_adaptive_color(VALUE object) {
10
+ return rb_respond_to(object, rb_intern("light")) && rb_respond_to(object, rb_intern("dark"));
11
+ }
12
+
9
13
  static VALUE lipgloss_join_horizontal_rb(VALUE self, VALUE position, VALUE strings) {
10
14
  Check_Type(strings, T_ARRAY);
11
15
 
12
- VALUE json_str = rb_funcall(strings, rb_intern("to_json"), 0);
13
- char *result = lipgloss_join_horizontal(NUM2DBL(position), StringValueCStr(json_str));
16
+ VALUE json_string = rb_funcall(strings, rb_intern("to_json"), 0);
17
+ char *result = lipgloss_join_horizontal(NUM2DBL(position), StringValueCStr(json_string));
14
18
  VALUE rb_result = rb_utf8_str_new_cstr(result);
15
19
 
16
20
  lipgloss_free(result);
@@ -21,8 +25,8 @@ static VALUE lipgloss_join_horizontal_rb(VALUE self, VALUE position, VALUE strin
21
25
  static VALUE lipgloss_join_vertical_rb(VALUE self, VALUE position, VALUE strings) {
22
26
  Check_Type(strings, T_ARRAY);
23
27
 
24
- VALUE json_str = rb_funcall(strings, rb_intern("to_json"), 0);
25
- char *result = lipgloss_join_vertical(NUM2DBL(position), StringValueCStr(json_str));
28
+ VALUE json_string = rb_funcall(strings, rb_intern("to_json"), 0);
29
+ char *result = lipgloss_join_vertical(NUM2DBL(position), StringValueCStr(json_string));
26
30
  VALUE rb_result = rb_utf8_str_new_cstr(result);
27
31
 
28
32
  lipgloss_free(result);
@@ -53,18 +57,55 @@ static VALUE lipgloss_size_rb(VALUE self, VALUE string) {
53
57
  }
54
58
 
55
59
  static VALUE lipgloss_place_rb(int argc, VALUE *argv, VALUE self) {
56
- VALUE width, height, horizontal_position, vertical_position, string;
57
- rb_scan_args(argc, argv, "5", &width, &height, &horizontal_position, &vertical_position, &string);
60
+ VALUE width, height, horizontal_position, vertical_position, string, opts;
61
+ rb_scan_args(argc, argv, "5:", &width, &height, &horizontal_position, &vertical_position, &string, &opts);
58
62
 
59
63
  Check_Type(string, T_STRING);
60
64
 
61
- char *result = lipgloss_place(
62
- NUM2INT(width),
63
- NUM2INT(height),
64
- NUM2DBL(horizontal_position),
65
- NUM2DBL(vertical_position),
66
- StringValueCStr(string)
67
- );
65
+ char *result;
66
+
67
+ if (!NIL_P(opts)) {
68
+ VALUE whitespace_chars = rb_hash_aref(opts, ID2SYM(rb_intern("whitespace_chars")));
69
+ VALUE whitespace_foreground = rb_hash_aref(opts, ID2SYM(rb_intern("whitespace_foreground")));
70
+
71
+ const char *ws_chars = NIL_P(whitespace_chars) ? "" : StringValueCStr(whitespace_chars);
72
+
73
+ if (!NIL_P(whitespace_foreground) && is_adaptive_color(whitespace_foreground)) {
74
+ VALUE light = rb_funcall(whitespace_foreground, rb_intern("light"), 0);
75
+ VALUE dark = rb_funcall(whitespace_foreground, rb_intern("dark"), 0);
76
+
77
+ result = lipgloss_place_with_whitespace_adaptive(
78
+ NUM2INT(width),
79
+ NUM2INT(height),
80
+ NUM2DBL(horizontal_position),
81
+ NUM2DBL(vertical_position),
82
+ StringValueCStr(string),
83
+ ws_chars,
84
+ StringValueCStr(light),
85
+ StringValueCStr(dark)
86
+ );
87
+ } else {
88
+ const char *ws_fg = NIL_P(whitespace_foreground) ? "" : StringValueCStr(whitespace_foreground);
89
+
90
+ result = lipgloss_place_with_whitespace(
91
+ NUM2INT(width),
92
+ NUM2INT(height),
93
+ NUM2DBL(horizontal_position),
94
+ NUM2DBL(vertical_position),
95
+ StringValueCStr(string),
96
+ ws_chars,
97
+ ws_fg
98
+ );
99
+ }
100
+ } else {
101
+ result = lipgloss_place(
102
+ NUM2INT(width),
103
+ NUM2INT(height),
104
+ NUM2DBL(horizontal_position),
105
+ NUM2DBL(vertical_position),
106
+ StringValueCStr(string)
107
+ );
108
+ }
68
109
 
69
110
  VALUE rb_result = rb_utf8_str_new_cstr(result);
70
111
 
@@ -121,7 +162,7 @@ static VALUE lipgloss_upstream_version_rb(VALUE self) {
121
162
  static VALUE lipgloss_version_rb(VALUE self) {
122
163
  VALUE gem_version = rb_const_get(self, rb_intern("VERSION"));
123
164
  VALUE upstream_version = lipgloss_upstream_version_rb(self);
124
- VALUE format_string = rb_utf8_str_new_cstr("lipgloss v%s (upstream v%s) [Go native extension]");
165
+ VALUE format_string = rb_utf8_str_new_cstr("lipgloss v%s (upstream %s) [Go native extension]");
125
166
 
126
167
  return rb_funcall(rb_mKernel, rb_intern("sprintf"), 3, format_string, gem_version, upstream_version);
127
168
  }
@@ -135,15 +176,16 @@ __attribute__((__visibility__("default"))) void Init_lipgloss(void) {
135
176
  Init_lipgloss_table();
136
177
  Init_lipgloss_list();
137
178
  Init_lipgloss_tree();
179
+ Init_lipgloss_color();
138
180
 
139
- rb_define_singleton_method(mLipgloss, "join_horizontal", lipgloss_join_horizontal_rb, 2);
140
- rb_define_singleton_method(mLipgloss, "join_vertical", lipgloss_join_vertical_rb, 2);
181
+ rb_define_singleton_method(mLipgloss, "_join_horizontal", lipgloss_join_horizontal_rb, 2);
182
+ rb_define_singleton_method(mLipgloss, "_join_vertical", lipgloss_join_vertical_rb, 2);
141
183
  rb_define_singleton_method(mLipgloss, "width", lipgloss_width_rb, 1);
142
184
  rb_define_singleton_method(mLipgloss, "height", lipgloss_height_rb, 1);
143
185
  rb_define_singleton_method(mLipgloss, "size", lipgloss_size_rb, 1);
144
- rb_define_singleton_method(mLipgloss, "place", lipgloss_place_rb, -1);
145
- rb_define_singleton_method(mLipgloss, "place_horizontal", lipgloss_place_horizontal_rb, 3);
146
- rb_define_singleton_method(mLipgloss, "place_vertical", lipgloss_place_vertical_rb, 3);
186
+ rb_define_singleton_method(mLipgloss, "_place", lipgloss_place_rb, -1);
187
+ rb_define_singleton_method(mLipgloss, "_place_horizontal", lipgloss_place_horizontal_rb, 3);
188
+ rb_define_singleton_method(mLipgloss, "_place_vertical", lipgloss_place_vertical_rb, 3);
147
189
  rb_define_singleton_method(mLipgloss, "has_dark_background?", lipgloss_has_dark_background_rb, 0);
148
190
  rb_define_singleton_method(mLipgloss, "upstream_version", lipgloss_upstream_version_rb, 0);
149
191
  rb_define_singleton_method(mLipgloss, "version", lipgloss_version_rb, 0);
@@ -68,9 +68,12 @@ void Init_lipgloss_style(void);
68
68
  void Init_lipgloss_table(void);
69
69
  void Init_lipgloss_list(void);
70
70
  void Init_lipgloss_tree(void);
71
+ void Init_lipgloss_color(void);
71
72
 
72
73
  void register_style_spacing_methods(void);
73
74
  void register_style_border_methods(void);
74
75
  void register_style_unset_methods(void);
75
76
 
77
+ int is_adaptive_color(VALUE object);
78
+
76
79
  #endif
data/ext/lipgloss/style.c CHANGED
@@ -103,10 +103,6 @@ static int is_complete_color(VALUE obj) {
103
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
104
  }
105
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
106
  // Color methods
111
107
 
112
108
  static VALUE style_foreground(VALUE self, VALUE color) {
@@ -348,6 +344,80 @@ static VALUE style_to_s(VALUE self) {
348
344
  return rb_result;
349
345
  }
350
346
 
347
+ // Getter methods
348
+
349
+ static VALUE style_get_bold(VALUE self) {
350
+ GET_STYLE(self, style);
351
+ return lipgloss_style_get_bold(style->handle) ? Qtrue : Qfalse;
352
+ }
353
+
354
+ static VALUE style_get_italic(VALUE self) {
355
+ GET_STYLE(self, style);
356
+ return lipgloss_style_get_italic(style->handle) ? Qtrue : Qfalse;
357
+ }
358
+
359
+ static VALUE style_get_underline(VALUE self) {
360
+ GET_STYLE(self, style);
361
+ return lipgloss_style_get_underline(style->handle) ? Qtrue : Qfalse;
362
+ }
363
+
364
+ static VALUE style_get_strikethrough(VALUE self) {
365
+ GET_STYLE(self, style);
366
+ return lipgloss_style_get_strikethrough(style->handle) ? Qtrue : Qfalse;
367
+ }
368
+
369
+ static VALUE style_get_reverse(VALUE self) {
370
+ GET_STYLE(self, style);
371
+ return lipgloss_style_get_reverse(style->handle) ? Qtrue : Qfalse;
372
+ }
373
+
374
+ static VALUE style_get_blink(VALUE self) {
375
+ GET_STYLE(self, style);
376
+ return lipgloss_style_get_blink(style->handle) ? Qtrue : Qfalse;
377
+ }
378
+
379
+ static VALUE style_get_faint(VALUE self) {
380
+ GET_STYLE(self, style);
381
+ return lipgloss_style_get_faint(style->handle) ? Qtrue : Qfalse;
382
+ }
383
+
384
+ static VALUE style_get_foreground(VALUE self) {
385
+ GET_STYLE(self, style);
386
+ char *result = lipgloss_style_get_foreground(style->handle);
387
+ if (result == NULL || result[0] == '\0') {
388
+ if (result) lipgloss_free(result);
389
+ return Qnil;
390
+ }
391
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
392
+ lipgloss_free(result);
393
+ return rb_result;
394
+ }
395
+
396
+ static VALUE style_get_background(VALUE self) {
397
+ GET_STYLE(self, style);
398
+ char *result = lipgloss_style_get_background(style->handle);
399
+
400
+ if (result == NULL || result[0] == '\0') {
401
+ if (result) lipgloss_free(result);
402
+ return Qnil;
403
+ }
404
+
405
+ VALUE rb_result = rb_utf8_str_new_cstr(result);
406
+ lipgloss_free(result);
407
+
408
+ return rb_result;
409
+ }
410
+
411
+ static VALUE style_get_width(VALUE self) {
412
+ GET_STYLE(self, style);
413
+ return INT2NUM(lipgloss_style_get_width(style->handle));
414
+ }
415
+
416
+ static VALUE style_get_height(VALUE self) {
417
+ GET_STYLE(self, style);
418
+ return INT2NUM(lipgloss_style_get_height(style->handle));
419
+ }
420
+
351
421
  void Init_lipgloss_style(void) {
352
422
  cStyle = rb_define_class_under(mLipgloss, "Style", rb_cObject);
353
423
 
@@ -356,7 +426,6 @@ void Init_lipgloss_style(void) {
356
426
  rb_define_method(cStyle, "initialize", style_initialize, 0);
357
427
  rb_define_method(cStyle, "render", style_render, 1);
358
428
 
359
- // Formatting
360
429
  rb_define_method(cStyle, "bold", style_bold, 1);
361
430
  rb_define_method(cStyle, "italic", style_italic, 1);
362
431
  rb_define_method(cStyle, "underline", style_underline, 1);
@@ -365,23 +434,19 @@ void Init_lipgloss_style(void) {
365
434
  rb_define_method(cStyle, "blink", style_blink, 1);
366
435
  rb_define_method(cStyle, "faint", style_faint, 1);
367
436
 
368
- // Colors
369
437
  rb_define_method(cStyle, "foreground", style_foreground, 1);
370
438
  rb_define_method(cStyle, "background", style_background, 1);
371
439
  rb_define_method(cStyle, "margin_background", style_margin_background, 1);
372
440
 
373
- // Size
374
441
  rb_define_method(cStyle, "width", style_width, 1);
375
442
  rb_define_method(cStyle, "height", style_height, 1);
376
443
  rb_define_method(cStyle, "max_width", style_max_width, 1);
377
444
  rb_define_method(cStyle, "max_height", style_max_height, 1);
378
445
 
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);
446
+ rb_define_method(cStyle, "_align", style_align, -1);
447
+ rb_define_method(cStyle, "_align_horizontal", style_align_horizontal, 1);
448
+ rb_define_method(cStyle, "_align_vertical", style_align_vertical, 1);
383
449
 
384
- // Other
385
450
  rb_define_method(cStyle, "inline", style_inline, 1);
386
451
  rb_define_method(cStyle, "tab_width", style_tab_width, 1);
387
452
  rb_define_method(cStyle, "underline_spaces", style_underline_spaces, 1);
@@ -391,7 +456,18 @@ void Init_lipgloss_style(void) {
391
456
  rb_define_method(cStyle, "inherit", style_inherit, 1);
392
457
  rb_define_method(cStyle, "to_s", style_to_s, 0);
393
458
 
394
- // Register methods from sub-files
459
+ rb_define_method(cStyle, "bold?", style_get_bold, 0);
460
+ rb_define_method(cStyle, "italic?", style_get_italic, 0);
461
+ rb_define_method(cStyle, "underline?", style_get_underline, 0);
462
+ rb_define_method(cStyle, "strikethrough?", style_get_strikethrough, 0);
463
+ rb_define_method(cStyle, "reverse?", style_get_reverse, 0);
464
+ rb_define_method(cStyle, "blink?", style_get_blink, 0);
465
+ rb_define_method(cStyle, "faint?", style_get_faint, 0);
466
+ rb_define_method(cStyle, "get_foreground", style_get_foreground, 0);
467
+ rb_define_method(cStyle, "get_background", style_get_background, 0);
468
+ rb_define_method(cStyle, "get_width", style_get_width, 0);
469
+ rb_define_method(cStyle, "get_height", style_get_height, 0);
470
+
395
471
  register_style_spacing_methods();
396
472
  register_style_border_methods();
397
473
  register_style_unset_methods();
@@ -50,6 +50,20 @@ static VALUE style_border_style(VALUE self, VALUE border_sym) {
50
50
 
51
51
  static VALUE style_border_foreground(VALUE self, VALUE color) {
52
52
  GET_STYLE(self, style);
53
+
54
+ if (is_adaptive_color(color)) {
55
+ VALUE light = rb_funcall(color, rb_intern("light"), 0);
56
+ VALUE dark = rb_funcall(color, rb_intern("dark"), 0);
57
+
58
+ unsigned long long new_handle = lipgloss_style_border_foreground_adaptive(
59
+ style->handle,
60
+ StringValueCStr(light),
61
+ StringValueCStr(dark)
62
+ );
63
+
64
+ return style_wrap(rb_class_of(self), new_handle);
65
+ }
66
+
53
67
  Check_Type(color, T_STRING);
54
68
  unsigned long long new_handle = lipgloss_style_border_foreground(style->handle, StringValueCStr(color));
55
69
  return style_wrap(rb_class_of(self), new_handle);
@@ -57,6 +71,20 @@ static VALUE style_border_foreground(VALUE self, VALUE color) {
57
71
 
58
72
  static VALUE style_border_background(VALUE self, VALUE color) {
59
73
  GET_STYLE(self, style);
74
+
75
+ if (is_adaptive_color(color)) {
76
+ VALUE light = rb_funcall(color, rb_intern("light"), 0);
77
+ VALUE dark = rb_funcall(color, rb_intern("dark"), 0);
78
+
79
+ unsigned long long new_handle = lipgloss_style_border_background_adaptive(
80
+ style->handle,
81
+ StringValueCStr(light),
82
+ StringValueCStr(dark)
83
+ );
84
+
85
+ return style_wrap(rb_class_of(self), new_handle);
86
+ }
87
+
60
88
  Check_Type(color, T_STRING);
61
89
  unsigned long long new_handle = lipgloss_style_border_background(style->handle, StringValueCStr(color));
62
90
  return style_wrap(rb_class_of(self), new_handle);
Binary file