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 +4 -4
- data/README.md +51 -22
- data/ext/lipgloss/color.c +158 -0
- data/ext/lipgloss/extconf.rb +11 -1
- data/ext/lipgloss/extension.c +61 -19
- data/ext/lipgloss/extension.h +3 -0
- data/ext/lipgloss/style.c +89 -13
- data/ext/lipgloss/style_border.c +28 -0
- data/go/build/darwin_amd64/liblipgloss.a +0 -0
- data/go/build/darwin_amd64/liblipgloss.h +21 -0
- data/go/color.go +168 -0
- data/go/layout.go +42 -0
- data/go/style.go +107 -0
- data/go/style_border.go +20 -0
- data/lib/lipgloss/3.2/lipgloss.bundle +0 -0
- data/lib/lipgloss/3.3/lipgloss.bundle +0 -0
- data/lib/lipgloss/3.4/lipgloss.bundle +0 -0
- data/lib/lipgloss/4.0/lipgloss.bundle +0 -0
- data/lib/lipgloss/color.rb +44 -8
- data/lib/lipgloss/position.rb +23 -0
- data/lib/lipgloss/style.rb +24 -0
- data/lib/lipgloss/version.rb +1 -1
- data/lib/lipgloss.rb +51 -1
- data/lipgloss.gemspec +2 -2
- metadata +9 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9ea95944023884864feb4b5e709264b23129b69357017288ea89f1994bbc7d53
|
|
4
|
+
data.tar.gz: 484b930da4da98dec979a6c17cfd690fa81f4c7aa29a172893c1aabbca3d2fa1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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>
|
|
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
|
|
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(
|
|
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(
|
|
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(
|
|
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,
|
|
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:
|
|
159
|
-
ansi:
|
|
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:
|
|
169
|
-
dark = Lipgloss::CompleteColor.new(true_color: "#FFF", ansi256:
|
|
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
|
|
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
|
|
406
|
-
|
|
407
|
-
| `Lipgloss.join_horizontal(position, strings)`
|
|
408
|
-
| `Lipgloss.join_vertical(position, strings)`
|
|
409
|
-
| `Lipgloss.width(string)`
|
|
410
|
-
| `Lipgloss.height(string)`
|
|
411
|
-
| `Lipgloss.size(string)`
|
|
412
|
-
| `Lipgloss.place(width, height,
|
|
413
|
-
| `Lipgloss.place_horizontal(width, position, string)`
|
|
414
|
-
| `Lipgloss.place_vertical(height, position, string)`
|
|
415
|
-
| `Lipgloss.has_dark_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
|
+
}
|
data/ext/lipgloss/extconf.rb
CHANGED
|
@@ -56,6 +56,16 @@ when /linux/
|
|
|
56
56
|
$LDFLAGS << " -lresolv" if find_library("resolv", "res_query")
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
$srcs = [
|
|
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}")
|
data/ext/lipgloss/extension.c
CHANGED
|
@@ -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
|
|
13
|
-
char *result = lipgloss_join_horizontal(NUM2DBL(position), StringValueCStr(
|
|
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
|
|
25
|
-
char *result = lipgloss_join_vertical(NUM2DBL(position), StringValueCStr(
|
|
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
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
|
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, "
|
|
140
|
-
rb_define_singleton_method(mLipgloss, "
|
|
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, "
|
|
145
|
-
rb_define_singleton_method(mLipgloss, "
|
|
146
|
-
rb_define_singleton_method(mLipgloss, "
|
|
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);
|
data/ext/lipgloss/extension.h
CHANGED
|
@@ -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
|
-
|
|
380
|
-
rb_define_method(cStyle, "
|
|
381
|
-
rb_define_method(cStyle, "
|
|
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
|
-
|
|
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();
|
data/ext/lipgloss/style_border.c
CHANGED
|
@@ -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
|