lipgloss 0.1.0 → 0.2.0
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/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/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 +7 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 822cdc4a08be4d36feab181fe8933cf9486c1eba70935eca9d73eb6a573d47f1
|
|
4
|
+
data.tar.gz: 2ac7c9626a365e2747050dd8b2cd067ccad05992b4c063b3dbb3668eff6dbc10
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e1ee9fc15a1935945789032584bdac9fb983614e24daf66aca646593ae262dcc9cd395f4e5e74ebbe8589ab2f378245e07c660af66d2baf184451f4c843934ed
|
|
7
|
+
data.tar.gz: f67ac668b982e0f6f06ffa6b1c17031ea491a90df729cc2e9f655e0c0ba78b7217020e39adc940be4c0f9864c7f3418f995dd282ffa29996a4dd9609be4b2389
|
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);
|
data/go/color.go
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
package main
|
|
2
|
+
|
|
3
|
+
import "C"
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"encoding/json"
|
|
7
|
+
"github.com/lucasb-eyer/go-colorful"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
//export lipgloss_color_blend_luv
|
|
11
|
+
func lipgloss_color_blend_luv(c1 *C.char, c2 *C.char, t C.double) *C.char {
|
|
12
|
+
color1, err := colorful.Hex(C.GoString(c1))
|
|
13
|
+
if err != nil {
|
|
14
|
+
return C.CString(C.GoString(c1))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
color2, err := colorful.Hex(C.GoString(c2))
|
|
18
|
+
if err != nil {
|
|
19
|
+
return C.CString(C.GoString(c1))
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
blended := color1.BlendLuv(color2, float64(t))
|
|
23
|
+
return C.CString(blended.Hex())
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
//export lipgloss_color_blend_rgb
|
|
27
|
+
func lipgloss_color_blend_rgb(c1 *C.char, c2 *C.char, t C.double) *C.char {
|
|
28
|
+
color1, err := colorful.Hex(C.GoString(c1))
|
|
29
|
+
if err != nil {
|
|
30
|
+
return C.CString(C.GoString(c1))
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
color2, err := colorful.Hex(C.GoString(c2))
|
|
34
|
+
if err != nil {
|
|
35
|
+
return C.CString(C.GoString(c1))
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
blended := color1.BlendRgb(color2, float64(t))
|
|
39
|
+
return C.CString(blended.Hex())
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//export lipgloss_color_blend_hcl
|
|
43
|
+
func lipgloss_color_blend_hcl(c1 *C.char, c2 *C.char, t C.double) *C.char {
|
|
44
|
+
color1, err := colorful.Hex(C.GoString(c1))
|
|
45
|
+
if err != nil {
|
|
46
|
+
return C.CString(C.GoString(c1))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
color2, err := colorful.Hex(C.GoString(c2))
|
|
50
|
+
if err != nil {
|
|
51
|
+
return C.CString(C.GoString(c1))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
blended := color1.BlendHcl(color2, float64(t))
|
|
55
|
+
return C.CString(blended.Hex())
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
//export lipgloss_color_blends
|
|
59
|
+
func lipgloss_color_blends(c1 *C.char, c2 *C.char, steps C.int, blendMode C.int) *C.char {
|
|
60
|
+
color1, err := colorful.Hex(C.GoString(c1))
|
|
61
|
+
if err != nil {
|
|
62
|
+
return C.CString("[]")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
color2, err := colorful.Hex(C.GoString(c2))
|
|
66
|
+
if err != nil {
|
|
67
|
+
return C.CString("[]")
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
n := int(steps)
|
|
71
|
+
colors := make([]string, n)
|
|
72
|
+
|
|
73
|
+
for i := 0; i < n; i++ {
|
|
74
|
+
t := float64(i) / float64(n-1)
|
|
75
|
+
if n == 1 {
|
|
76
|
+
t = 0
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
var blended colorful.Color
|
|
80
|
+
switch int(blendMode) {
|
|
81
|
+
case 0: // LUV
|
|
82
|
+
blended = color1.BlendLuv(color2, t)
|
|
83
|
+
case 1: // RGB
|
|
84
|
+
blended = color1.BlendRgb(color2, t)
|
|
85
|
+
case 2: // HCL
|
|
86
|
+
blended = color1.BlendHcl(color2, t)
|
|
87
|
+
default:
|
|
88
|
+
blended = color1.BlendLuv(color2, t)
|
|
89
|
+
}
|
|
90
|
+
colors[i] = blended.Hex()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
result, _ := json.Marshal(colors)
|
|
94
|
+
return C.CString(string(result))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//export lipgloss_color_grid
|
|
98
|
+
func lipgloss_color_grid(x0y0 *C.char, x1y0 *C.char, x0y1 *C.char, x1y1 *C.char, xSteps C.int, ySteps C.int, blendMode C.int) *C.char {
|
|
99
|
+
c00, err := colorful.Hex(C.GoString(x0y0))
|
|
100
|
+
if err != nil {
|
|
101
|
+
return C.CString("[]")
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
c10, err := colorful.Hex(C.GoString(x1y0))
|
|
105
|
+
if err != nil {
|
|
106
|
+
return C.CString("[]")
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
c01, err := colorful.Hex(C.GoString(x0y1))
|
|
110
|
+
if err != nil {
|
|
111
|
+
return C.CString("[]")
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
c11, err := colorful.Hex(C.GoString(x1y1))
|
|
115
|
+
if err != nil {
|
|
116
|
+
return C.CString("[]")
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
nx := int(xSteps)
|
|
120
|
+
ny := int(ySteps)
|
|
121
|
+
mode := int(blendMode)
|
|
122
|
+
|
|
123
|
+
blendFunc := func(a, b colorful.Color, t float64) colorful.Color {
|
|
124
|
+
switch mode {
|
|
125
|
+
case 0: // LUV
|
|
126
|
+
return a.BlendLuv(b, t)
|
|
127
|
+
case 1: // RGB
|
|
128
|
+
return a.BlendRgb(b, t)
|
|
129
|
+
case 2: // HCL
|
|
130
|
+
return a.BlendHcl(b, t)
|
|
131
|
+
default:
|
|
132
|
+
return a.BlendLuv(b, t)
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
x0 := make([]colorful.Color, ny)
|
|
137
|
+
x1 := make([]colorful.Color, ny)
|
|
138
|
+
|
|
139
|
+
for y := 0; y < ny; y++ {
|
|
140
|
+
t := float64(y) / float64(ny)
|
|
141
|
+
|
|
142
|
+
if ny == 1 {
|
|
143
|
+
t = 0
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
x0[y] = blendFunc(c00, c01, t)
|
|
147
|
+
x1[y] = blendFunc(c10, c11, t)
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
grid := make([][]string, ny)
|
|
151
|
+
|
|
152
|
+
for y := 0; y < ny; y++ {
|
|
153
|
+
grid[y] = make([]string, nx)
|
|
154
|
+
|
|
155
|
+
for x := 0; x < nx; x++ {
|
|
156
|
+
t := float64(x) / float64(nx)
|
|
157
|
+
|
|
158
|
+
if nx == 1 {
|
|
159
|
+
t = 0
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
grid[y][x] = blendFunc(x0[y], x1[y], t).Hex()
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
result, _ := json.Marshal(grid)
|
|
167
|
+
return C.CString(string(result))
|
|
168
|
+
}
|
data/go/layout.go
CHANGED
|
@@ -49,6 +49,48 @@ func lipgloss_place(width C.int, height C.int, horizontalPosition C.double, vert
|
|
|
49
49
|
return C.CString(result)
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
+
//export lipgloss_place_with_whitespace
|
|
53
|
+
func lipgloss_place_with_whitespace(width C.int, height C.int, horizontalPosition C.double, verticalPosition C.double, text *C.char, whitespaceChars *C.char, whitespaceForeground *C.char) *C.char {
|
|
54
|
+
opts := []lipgloss.WhitespaceOption{}
|
|
55
|
+
|
|
56
|
+
wsChars := C.GoString(whitespaceChars)
|
|
57
|
+
if wsChars != "" {
|
|
58
|
+
opts = append(opts, lipgloss.WithWhitespaceChars(wsChars))
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
wsFg := C.GoString(whitespaceForeground)
|
|
62
|
+
if wsFg != "" {
|
|
63
|
+
opts = append(opts, lipgloss.WithWhitespaceForeground(lipgloss.Color(wsFg)))
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
result := lipgloss.Place(int(width), int(height), lipgloss.Position(horizontalPosition), lipgloss.Position(verticalPosition), C.GoString(text), opts...)
|
|
67
|
+
return C.CString(result)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//export lipgloss_place_with_whitespace_adaptive
|
|
71
|
+
func lipgloss_place_with_whitespace_adaptive(width C.int, height C.int, horizontalPosition C.double, verticalPosition C.double, text *C.char, whitespaceChars *C.char, whitespaceForegroundLight *C.char, whitespaceForegroundDark *C.char) *C.char {
|
|
72
|
+
opts := []lipgloss.WhitespaceOption{}
|
|
73
|
+
|
|
74
|
+
wsChars := C.GoString(whitespaceChars)
|
|
75
|
+
if wsChars != "" {
|
|
76
|
+
opts = append(opts, lipgloss.WithWhitespaceChars(wsChars))
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
wsFgLight := C.GoString(whitespaceForegroundLight)
|
|
80
|
+
wsFgDark := C.GoString(whitespaceForegroundDark)
|
|
81
|
+
|
|
82
|
+
if wsFgLight != "" || wsFgDark != "" {
|
|
83
|
+
opts = append(opts, lipgloss.WithWhitespaceForeground(lipgloss.AdaptiveColor{
|
|
84
|
+
Light: wsFgLight,
|
|
85
|
+
Dark: wsFgDark,
|
|
86
|
+
}))
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
result := lipgloss.Place(int(width), int(height), lipgloss.Position(horizontalPosition), lipgloss.Position(verticalPosition), C.GoString(text), opts...)
|
|
90
|
+
|
|
91
|
+
return C.CString(result)
|
|
92
|
+
}
|
|
93
|
+
|
|
52
94
|
//export lipgloss_place_horizontal
|
|
53
95
|
func lipgloss_place_horizontal(width C.int, position C.double, text *C.char) *C.char {
|
|
54
96
|
result := lipgloss.PlaceHorizontal(int(width), lipgloss.Position(position), C.GoString(text))
|
data/go/style.go
CHANGED
|
@@ -279,3 +279,110 @@ func lipgloss_style_string(id C.ulonglong) *C.char {
|
|
|
279
279
|
style := getStyle(uint64(id))
|
|
280
280
|
return C.CString(style.String())
|
|
281
281
|
}
|
|
282
|
+
|
|
283
|
+
// Getter methods
|
|
284
|
+
|
|
285
|
+
//export lipgloss_style_get_bold
|
|
286
|
+
func lipgloss_style_get_bold(id C.ulonglong) C.int {
|
|
287
|
+
style := getStyle(uint64(id))
|
|
288
|
+
if style.GetBold() {
|
|
289
|
+
return 1
|
|
290
|
+
}
|
|
291
|
+
return 0
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
//export lipgloss_style_get_italic
|
|
295
|
+
func lipgloss_style_get_italic(id C.ulonglong) C.int {
|
|
296
|
+
style := getStyle(uint64(id))
|
|
297
|
+
if style.GetItalic() {
|
|
298
|
+
return 1
|
|
299
|
+
}
|
|
300
|
+
return 0
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
//export lipgloss_style_get_underline
|
|
304
|
+
func lipgloss_style_get_underline(id C.ulonglong) C.int {
|
|
305
|
+
style := getStyle(uint64(id))
|
|
306
|
+
if style.GetUnderline() {
|
|
307
|
+
return 1
|
|
308
|
+
}
|
|
309
|
+
return 0
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
//export lipgloss_style_get_strikethrough
|
|
313
|
+
func lipgloss_style_get_strikethrough(id C.ulonglong) C.int {
|
|
314
|
+
style := getStyle(uint64(id))
|
|
315
|
+
if style.GetStrikethrough() {
|
|
316
|
+
return 1
|
|
317
|
+
}
|
|
318
|
+
return 0
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
//export lipgloss_style_get_reverse
|
|
322
|
+
func lipgloss_style_get_reverse(id C.ulonglong) C.int {
|
|
323
|
+
style := getStyle(uint64(id))
|
|
324
|
+
if style.GetReverse() {
|
|
325
|
+
return 1
|
|
326
|
+
}
|
|
327
|
+
return 0
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
//export lipgloss_style_get_blink
|
|
331
|
+
func lipgloss_style_get_blink(id C.ulonglong) C.int {
|
|
332
|
+
style := getStyle(uint64(id))
|
|
333
|
+
if style.GetBlink() {
|
|
334
|
+
return 1
|
|
335
|
+
}
|
|
336
|
+
return 0
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
//export lipgloss_style_get_faint
|
|
340
|
+
func lipgloss_style_get_faint(id C.ulonglong) C.int {
|
|
341
|
+
style := getStyle(uint64(id))
|
|
342
|
+
if style.GetFaint() {
|
|
343
|
+
return 1
|
|
344
|
+
}
|
|
345
|
+
return 0
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// terminalColorToString converts a TerminalColor to its string representation
|
|
349
|
+
func terminalColorToString(tc lipgloss.TerminalColor) string {
|
|
350
|
+
if tc == nil {
|
|
351
|
+
return ""
|
|
352
|
+
}
|
|
353
|
+
switch c := tc.(type) {
|
|
354
|
+
case lipgloss.Color:
|
|
355
|
+
return string(c)
|
|
356
|
+
case lipgloss.NoColor:
|
|
357
|
+
return ""
|
|
358
|
+
default:
|
|
359
|
+
// For adaptive/complete colors, we can't easily extract a single value
|
|
360
|
+
return ""
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
//export lipgloss_style_get_foreground
|
|
365
|
+
func lipgloss_style_get_foreground(id C.ulonglong) *C.char {
|
|
366
|
+
style := getStyle(uint64(id))
|
|
367
|
+
color := terminalColorToString(style.GetForeground())
|
|
368
|
+
return C.CString(color)
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
//export lipgloss_style_get_background
|
|
372
|
+
func lipgloss_style_get_background(id C.ulonglong) *C.char {
|
|
373
|
+
style := getStyle(uint64(id))
|
|
374
|
+
color := terminalColorToString(style.GetBackground())
|
|
375
|
+
return C.CString(color)
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
//export lipgloss_style_get_width
|
|
379
|
+
func lipgloss_style_get_width(id C.ulonglong) C.int {
|
|
380
|
+
style := getStyle(uint64(id))
|
|
381
|
+
return C.int(style.GetWidth())
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
//export lipgloss_style_get_height
|
|
385
|
+
func lipgloss_style_get_height(id C.ulonglong) C.int {
|
|
386
|
+
style := getStyle(uint64(id))
|
|
387
|
+
return C.int(style.GetHeight())
|
|
388
|
+
}
|
data/go/style_border.go
CHANGED
|
@@ -114,12 +114,32 @@ func lipgloss_style_border_foreground(id C.ulonglong, color *C.char) C.ulonglong
|
|
|
114
114
|
return C.ulonglong(allocStyle(style))
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
+
//export lipgloss_style_border_foreground_adaptive
|
|
118
|
+
func lipgloss_style_border_foreground_adaptive(id C.ulonglong, light *C.char, dark *C.char) C.ulonglong {
|
|
119
|
+
style := getStyle(uint64(id)).BorderForeground(lipgloss.AdaptiveColor{
|
|
120
|
+
Light: C.GoString(light),
|
|
121
|
+
Dark: C.GoString(dark),
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
return C.ulonglong(allocStyle(style))
|
|
125
|
+
}
|
|
126
|
+
|
|
117
127
|
//export lipgloss_style_border_background
|
|
118
128
|
func lipgloss_style_border_background(id C.ulonglong, color *C.char) C.ulonglong {
|
|
119
129
|
style := getStyle(uint64(id)).BorderBackground(lipgloss.Color(C.GoString(color)))
|
|
120
130
|
return C.ulonglong(allocStyle(style))
|
|
121
131
|
}
|
|
122
132
|
|
|
133
|
+
//export lipgloss_style_border_background_adaptive
|
|
134
|
+
func lipgloss_style_border_background_adaptive(id C.ulonglong, light *C.char, dark *C.char) C.ulonglong {
|
|
135
|
+
style := getStyle(uint64(id)).BorderBackground(lipgloss.AdaptiveColor{
|
|
136
|
+
Light: C.GoString(light),
|
|
137
|
+
Dark: C.GoString(dark),
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
return C.ulonglong(allocStyle(style))
|
|
141
|
+
}
|
|
142
|
+
|
|
123
143
|
//export lipgloss_style_border_top
|
|
124
144
|
func lipgloss_style_border_top(id C.ulonglong, value C.int) C.ulonglong {
|
|
125
145
|
style := getStyle(uint64(id)).BorderTop(value != 0)
|
data/lib/lipgloss/color.rb
CHANGED
|
@@ -7,6 +7,42 @@ module Lipgloss
|
|
|
7
7
|
# type complete_color_hash = { true_color: String, ansi256: String, ansi: String }
|
|
8
8
|
# type complete_adaptive_color_hash = { light: complete_color_hash, dark: complete_color_hash }
|
|
9
9
|
|
|
10
|
+
module ANSIColor
|
|
11
|
+
# @rbs!
|
|
12
|
+
# type ansi_color_symbol = :black | :red | :green | :yellow | :blue | :magenta | :cyan | :white | :bright_black | :bright_red | :bright_green | :bright_yellow | :bright_blue | :bright_magenta | :bright_cyan | :bright_white
|
|
13
|
+
# type ansi_color_value = ansi_color_symbol | Symbol | String | Integer
|
|
14
|
+
|
|
15
|
+
COLORS = {
|
|
16
|
+
black: "0",
|
|
17
|
+
red: "1",
|
|
18
|
+
green: "2",
|
|
19
|
+
yellow: "3",
|
|
20
|
+
blue: "4",
|
|
21
|
+
magenta: "5",
|
|
22
|
+
cyan: "6",
|
|
23
|
+
white: "7",
|
|
24
|
+
bright_black: "8",
|
|
25
|
+
bright_red: "9",
|
|
26
|
+
bright_green: "10",
|
|
27
|
+
bright_yellow: "11",
|
|
28
|
+
bright_blue: "12",
|
|
29
|
+
bright_magenta: "13",
|
|
30
|
+
bright_cyan: "14",
|
|
31
|
+
bright_white: "15"
|
|
32
|
+
}.freeze #: Hash[Symbol, String]
|
|
33
|
+
|
|
34
|
+
# @rbs value: ansi_color_value
|
|
35
|
+
# @rbs return: String
|
|
36
|
+
def self.resolve(value)
|
|
37
|
+
case value
|
|
38
|
+
when Symbol then COLORS.fetch(value) { raise ArgumentError, "Unknown ANSI color: #{value.inspect}" }
|
|
39
|
+
when String then value
|
|
40
|
+
when Integer then value.to_s
|
|
41
|
+
else raise ArgumentError, "ANSI color must be a Symbol, String, or Integer, got #{value.class}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
10
46
|
# Adaptive color that changes based on terminal background
|
|
11
47
|
#
|
|
12
48
|
# @example
|
|
@@ -38,8 +74,8 @@ module Lipgloss
|
|
|
38
74
|
# @example
|
|
39
75
|
# color = Lipgloss::CompleteColor.new(
|
|
40
76
|
# true_color: "#0000FF",
|
|
41
|
-
# ansi256:
|
|
42
|
-
# ansi:
|
|
77
|
+
# ansi256: 21,
|
|
78
|
+
# ansi: :blue
|
|
43
79
|
# )
|
|
44
80
|
class CompleteColor
|
|
45
81
|
# @rbs @true_color: String
|
|
@@ -51,13 +87,13 @@ module Lipgloss
|
|
|
51
87
|
attr_reader :ansi #: String
|
|
52
88
|
|
|
53
89
|
# @rbs true_color: String -- 24-bit color (e.g., "#0000FF")
|
|
54
|
-
# @rbs ansi256:
|
|
55
|
-
# @rbs ansi:
|
|
90
|
+
# @rbs ansi256: ANSIColor::ansi_color_value -- 8-bit ANSI color (0-255, or symbol for 0-15)
|
|
91
|
+
# @rbs ansi: ANSIColor::ansi_color_value -- 4-bit ANSI color (:red, :blue, etc., or 0-15)
|
|
56
92
|
# @rbs return: void
|
|
57
93
|
def initialize(true_color:, ansi256:, ansi:)
|
|
58
94
|
@true_color = true_color
|
|
59
|
-
@ansi256 = ansi256
|
|
60
|
-
@ansi = ansi
|
|
95
|
+
@ansi256 = ANSIColor.resolve(ansi256)
|
|
96
|
+
@ansi = ANSIColor.resolve(ansi)
|
|
61
97
|
end
|
|
62
98
|
|
|
63
99
|
# @rbs return: complete_color_hash
|
|
@@ -71,8 +107,8 @@ module Lipgloss
|
|
|
71
107
|
#
|
|
72
108
|
# @example
|
|
73
109
|
# color = Lipgloss::CompleteAdaptiveColor.new(
|
|
74
|
-
# light: Lipgloss::CompleteColor.new(true_color: "#000", ansi256:
|
|
75
|
-
# dark: Lipgloss::CompleteColor.new(true_color: "#FFF", ansi256:
|
|
110
|
+
# light: Lipgloss::CompleteColor.new(true_color: "#000", ansi256: :black, ansi: :black),
|
|
111
|
+
# dark: Lipgloss::CompleteColor.new(true_color: "#FFF", ansi256: :bright_white, ansi: :bright_white)
|
|
76
112
|
# )
|
|
77
113
|
class CompleteAdaptiveColor
|
|
78
114
|
# @rbs @light: CompleteColor
|
data/lib/lipgloss/position.rb
CHANGED
|
@@ -23,5 +23,28 @@ module Lipgloss
|
|
|
23
23
|
|
|
24
24
|
# Center alignment (0.5)
|
|
25
25
|
CENTER = 0.5
|
|
26
|
+
|
|
27
|
+
# @rbs!
|
|
28
|
+
# type position_symbol = :top | :bottom | :left | :right | :center
|
|
29
|
+
# type position_value = position_symbol | Symbol | String | Integer | Float
|
|
30
|
+
|
|
31
|
+
SYMBOLS = {
|
|
32
|
+
top: TOP,
|
|
33
|
+
bottom: BOTTOM,
|
|
34
|
+
left: LEFT,
|
|
35
|
+
right: RIGHT,
|
|
36
|
+
center: CENTER
|
|
37
|
+
}.freeze #: Hash[Symbol, Float]
|
|
38
|
+
|
|
39
|
+
# @rbs value: position_value
|
|
40
|
+
# @rbs return: Float
|
|
41
|
+
def self.resolve(value)
|
|
42
|
+
case value
|
|
43
|
+
when Symbol then SYMBOLS.fetch(value) { raise ArgumentError, "Unknown position: #{value.inspect}" }
|
|
44
|
+
when String then SYMBOLS.fetch(value.to_sym) { raise ArgumentError, "Unknown position: #{value.inspect}" }
|
|
45
|
+
when Numeric then value.to_f
|
|
46
|
+
else raise ArgumentError, "Position must be a Symbol or Numeric, got #{value.class}"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
26
49
|
end
|
|
27
50
|
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
4
|
+
module Lipgloss
|
|
5
|
+
class Style
|
|
6
|
+
# @rbs *positions: Position::position_value
|
|
7
|
+
# @rbs return: Style
|
|
8
|
+
def align(*positions)
|
|
9
|
+
_align(*positions.map { |p| Position.resolve(p) })
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
# @rbs position: Position::position_value
|
|
13
|
+
# @rbs return: Style
|
|
14
|
+
def align_horizontal(position)
|
|
15
|
+
_align_horizontal(Position.resolve(position))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @rbs position: Position::position_value
|
|
19
|
+
# @rbs return: Style
|
|
20
|
+
def align_vertical(position)
|
|
21
|
+
_align_vertical(Position.resolve(position))
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
data/lib/lipgloss/version.rb
CHANGED
data/lib/lipgloss.rb
CHANGED
|
@@ -2,10 +2,18 @@
|
|
|
2
2
|
# rbs_inline: enabled
|
|
3
3
|
|
|
4
4
|
require_relative "lipgloss/version"
|
|
5
|
-
|
|
5
|
+
|
|
6
|
+
begin
|
|
7
|
+
major, minor, _patch = RUBY_VERSION.split(".") #: [String, String, String]
|
|
8
|
+
require_relative "lipgloss/#{major}.#{minor}/lipgloss"
|
|
9
|
+
rescue LoadError
|
|
10
|
+
require_relative "lipgloss/lipgloss"
|
|
11
|
+
end
|
|
12
|
+
|
|
6
13
|
require_relative "lipgloss/position"
|
|
7
14
|
require_relative "lipgloss/border"
|
|
8
15
|
require_relative "lipgloss/color"
|
|
16
|
+
require_relative "lipgloss/style"
|
|
9
17
|
require_relative "lipgloss/table"
|
|
10
18
|
|
|
11
19
|
module Lipgloss
|
|
@@ -24,4 +32,46 @@ module Lipgloss
|
|
|
24
32
|
ASCII_BORDER = Border::ASCII #: Symbol
|
|
25
33
|
|
|
26
34
|
NO_TAB_CONVERSION = -1 #: Integer
|
|
35
|
+
|
|
36
|
+
class << self
|
|
37
|
+
# @rbs position: Position::position_value
|
|
38
|
+
# @rbs *strings: String
|
|
39
|
+
# @rbs return: String
|
|
40
|
+
def join_horizontal(position, *strings)
|
|
41
|
+
_join_horizontal(Position.resolve(position), strings)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @rbs position: Position::position_value
|
|
45
|
+
# @rbs *strings: String
|
|
46
|
+
# @rbs return: String
|
|
47
|
+
def join_vertical(position, *strings)
|
|
48
|
+
_join_vertical(Position.resolve(position), strings)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# @rbs width: Integer
|
|
52
|
+
# @rbs height: Integer
|
|
53
|
+
# @rbs horizontal: Position::position_value
|
|
54
|
+
# @rbs vertical: Position::position_value
|
|
55
|
+
# @rbs string: String
|
|
56
|
+
# @rbs return: String
|
|
57
|
+
def place(width, height, horizontal, vertical, string, **opts)
|
|
58
|
+
_place(width, height, Position.resolve(horizontal), Position.resolve(vertical), string, **opts)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# @rbs width: Integer
|
|
62
|
+
# @rbs position: Position::position_value
|
|
63
|
+
# @rbs string: String
|
|
64
|
+
# @rbs return: String
|
|
65
|
+
def place_horizontal(width, position, string)
|
|
66
|
+
_place_horizontal(width, Position.resolve(position), string)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# @rbs height: Integer
|
|
70
|
+
# @rbs position: Position::position_value
|
|
71
|
+
# @rbs string: String
|
|
72
|
+
# @rbs return: String
|
|
73
|
+
def place_vertical(height, position, string)
|
|
74
|
+
_place_vertical(height, Position.resolve(position), string)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
27
77
|
end
|
data/lipgloss.gemspec
CHANGED
|
@@ -8,8 +8,8 @@ Gem::Specification.new do |spec|
|
|
|
8
8
|
spec.authors = ["Marco Roth"]
|
|
9
9
|
spec.email = ["marco.roth@intergga.ch"]
|
|
10
10
|
|
|
11
|
-
spec.summary = "Ruby wrapper for Charm's lipgloss CSS-like terminal styling library."
|
|
12
|
-
spec.description =
|
|
11
|
+
spec.summary = "Ruby wrapper for Charm's lipgloss. CSS-like terminal styling library."
|
|
12
|
+
spec.description = "Style Definitions for Nice Terminal Layouts. Built with TUIs in mind."
|
|
13
13
|
spec.homepage = "https://github.com/marcoroth/lipgloss-ruby"
|
|
14
14
|
spec.license = "MIT"
|
|
15
15
|
spec.required_ruby_version = ">= 3.2.0"
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: lipgloss
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Marco Roth
|
|
@@ -9,7 +9,7 @@ bindir: bin
|
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
12
|
-
description:
|
|
12
|
+
description: Style Definitions for Nice Terminal Layouts. Built with TUIs in mind.
|
|
13
13
|
email:
|
|
14
14
|
- marco.roth@intergga.ch
|
|
15
15
|
executables: []
|
|
@@ -19,6 +19,7 @@ extra_rdoc_files: []
|
|
|
19
19
|
files:
|
|
20
20
|
- LICENSE.txt
|
|
21
21
|
- README.md
|
|
22
|
+
- ext/lipgloss/color.c
|
|
22
23
|
- ext/lipgloss/extconf.rb
|
|
23
24
|
- ext/lipgloss/extension.c
|
|
24
25
|
- ext/lipgloss/extension.h
|
|
@@ -29,6 +30,7 @@ files:
|
|
|
29
30
|
- ext/lipgloss/style_unset.c
|
|
30
31
|
- ext/lipgloss/table.c
|
|
31
32
|
- ext/lipgloss/tree.c
|
|
33
|
+
- go/color.go
|
|
32
34
|
- go/go.mod
|
|
33
35
|
- go/go.sum
|
|
34
36
|
- go/layout.go
|
|
@@ -44,6 +46,7 @@ files:
|
|
|
44
46
|
- lib/lipgloss/border.rb
|
|
45
47
|
- lib/lipgloss/color.rb
|
|
46
48
|
- lib/lipgloss/position.rb
|
|
49
|
+
- lib/lipgloss/style.rb
|
|
47
50
|
- lib/lipgloss/table.rb
|
|
48
51
|
- lib/lipgloss/version.rb
|
|
49
52
|
- lipgloss.gemspec
|
|
@@ -69,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
69
72
|
- !ruby/object:Gem::Version
|
|
70
73
|
version: '0'
|
|
71
74
|
requirements: []
|
|
72
|
-
rubygems_version:
|
|
75
|
+
rubygems_version: 4.0.3
|
|
73
76
|
specification_version: 4
|
|
74
|
-
summary: Ruby wrapper for Charm's lipgloss CSS-like terminal styling library.
|
|
77
|
+
summary: Ruby wrapper for Charm's lipgloss. CSS-like terminal styling library.
|
|
75
78
|
test_files: []
|