sai 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0c45105e60b5f7a3a93d837080975996e96a340aef0ad3fd86cd4b5a1be17e8f
4
- data.tar.gz: baf93c18ef40221c86c329deeeaabbe7a3619744d3a80a9349314624a4af3995
3
+ metadata.gz: '091a65a91b7e31cfea072bfad910f4af966edf3370301aa1bfbad8e6292d8e25'
4
+ data.tar.gz: 2296a5bb8b8b8d4c713b91afdbd777d7e69b16dd3550683d8a799dc6ac9c434d
5
5
  SHA512:
6
- metadata.gz: c1540fe3fd55f0a338ff04ff6f9794e831b831c040637f4cdd4f0de0ab0a689a55f95d5c1a744f3ae25b0bc7452983044568e83b6e665439672142cd2abd811b
7
- data.tar.gz: 4244b0401b7fd0af26665a0a5b5622dd09bd364e4166bc8d12a6c69f94a52b09511d56afe2cd8eaedf1401c402b3ba63845aa900c147e408312221dcc243e21d
6
+ metadata.gz: 548ca06d57fe14768900f6d04191b52d876c38a9c5cca96b26da9d2c8afc3b7dffdd44b9d075b92bda97d1d80e2b6b75d3d8782c3e592d1a4547dfc72dceba1f
7
+ data.tar.gz: 48d9f58551111cd95a61c7c11ba2e83506239bf7e4805c93a3c38c653f28dfb94680637f35cf4a0325702ad4fe320f32060d794b26be2c308dd0b216f9cfbf64
data/CHANGELOG.md CHANGED
@@ -6,6 +6,13 @@ The format is based on [Keep a Changelog], and this project adheres to [Break Ve
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.3.2] - 2025-01-22
10
+
11
+ ### Added
12
+
13
+ * [#15](https://github.com/aaronmallen/sai/pull/15) - Add support for registering custom named colors by
14
+ [@aaronmallen](https://github.com/aaronmallen)
15
+
9
16
  ## [0.3.1] - 2025-01-22
10
17
 
11
18
  ### Added
@@ -64,7 +71,8 @@ The format is based on [Keep a Changelog], and this project adheres to [Break Ve
64
71
 
65
72
  <!-- versions -->
66
73
 
67
- [Unreleased]: https://github.com/aaronmallen/sai/compare/0.3.1..HEAD
74
+ [Unreleased]: https://github.com/aaronmallen/sai/compare/0.3.2..HEAD
75
+ [0.3.2]: https://github.com/aaronmallen/sai/compare/0.3.1..0.3.2
68
76
  [0.3.1]: https://github.com/aaronmallen/sai/compare/0.3.0..0.3.1
69
77
  [0.3.0]: https://github.com/aaronmallen/sai/compare/0.2.0..0.3.0
70
78
  [0.2.0]: https://github.com/aaronmallen/sai/compare/0.1.0..0.2.0
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![Sai Codacy grade](https://img.shields.io/codacy/grade/0f9a91b573ed4768a773867b95ed4894/main?style=for-the-badge&logo=codacy&logoColor=white&logoSize=auto)](https://app.codacy.com/gh/aaronmallen/sai)
5
5
  [![Sai Codacy coverage](https://img.shields.io/codacy/coverage/0f9a91b573ed4768a773867b95ed4894/main?style=for-the-badge&logo=codacy&logoColor=white&logoSize=auto)](https://app.codacy.com/gh/aaronmallen/sai/coverage)
6
6
  [![Sai License](https://img.shields.io/github/license/aaronmallen/sai?style=for-the-badge&logo=opensourceinitiative&logoColor=white&logoSize=auto)](./LICENSE)
7
- [![Sai Docs](https://img.shields.io/badge/rubydoc-blue?style=for-the-badge&logo=readthedocs&logoColor=white&logoSize=auto&label=docs)](https://rubydoc.info/gems/sai/0.3.1)
7
+ [![Sai Docs](https://img.shields.io/badge/rubydoc-blue?style=for-the-badge&logo=readthedocs&logoColor=white&logoSize=auto&label=docs)](https://rubydoc.info/gems/sai/0.3.2)
8
8
  [![Sai Open Issues](https://img.shields.io/github/issues-search/aaronmallen/sai?query=state%3Aopen&style=for-the-badge&logo=github&logoColor=white&logoSize=auto&label=issues&color=red)](https://github.com/aaronmallen/sai/issues?q=state%3Aopen%20)
9
9
 
10
10
  An elegant color management system for crafting sophisticated CLI applications
@@ -88,7 +88,7 @@ puts text.stripped # Get plain text
88
88
  ## Documentation
89
89
 
90
90
  * [Complete Usage Guide](docs/USAGE.md) - Comprehensive documentation of all features
91
- * [API Documentation](https://rubydoc.info/gems/sai/0.3.1) - Detailed API reference
91
+ * [API Documentation](https://rubydoc.info/gems/sai/0.3.2) - Detailed API reference
92
92
 
93
93
  ## Contributing
94
94
 
data/docs/USAGE.md CHANGED
@@ -107,6 +107,20 @@ For a complete list of available colors, see:
107
107
  * [Online Color Reference](https://github.com/aaronmallen/sai/blob/main/docs/AVAILABLE_NAMED_COLORS.md)
108
108
  * `Sai::NamedColors.names` in your code
109
109
 
110
+ #### Registering Custom Named Colors
111
+
112
+ Sai allows you to register custom named colors for easy reuse with `Sai.register`:
113
+
114
+ ```ruby
115
+ # Register custom colors
116
+ Sai.register(:my_color, '#CF4C5F')
117
+
118
+ # or alternatively
119
+ Sai.register(:my_color, [207, 76, 95])
120
+
121
+ Sai.my_color.decorate('Hello, world!')
122
+ ```
123
+
110
124
  ### Color Manipulation
111
125
 
112
126
  Adjust the brightness of colors:
@@ -52,6 +52,7 @@ module Sai
52
52
  methods = collect_delegatable_methods.reject { |m| ignored_methods.include?(m) }
53
53
 
54
54
  methods.each do |method|
55
+ klass.undef_method(method) if klass.method_defined?(method)
55
56
  klass.define_method(method) do |*args, **kwargs|
56
57
  Decorator.new(mode: Sai.mode.auto).public_send(method, *args, **kwargs)
57
58
  end
@@ -749,15 +749,27 @@ module Sai
749
749
  # def yellow_green: () -> Decorator
750
750
  # def yellow_system: () -> Decorator
751
751
 
752
- Sai::NamedColors.names.each do |color|
753
- define_method(color) do
754
- apply_named_color(:foreground, color)
755
- end
756
- define_method(:"on_#{color}") do
757
- apply_named_color(:background, color)
752
+ # Install a color method on the {Decorator} class
753
+ #
754
+ # @author {https://aaronmallen.me Aaron Allen}
755
+ # @since 0.3.2
756
+ #
757
+ # @api private
758
+ #
759
+ # @param color_name [Symbol] the name of the color to install
760
+ #
761
+ # @return [void]
762
+ # @rbs (Symbol color_name) -> void
763
+ def self.install(color_name)
764
+ { color_name => :foreground, :"on_#{color_name}" => :background }.each do |method_name, style_type|
765
+ # @type var style_type: Sai::Conversion::ColorSequence::style_type
766
+ Sai::Decorator.undef_method(method_name) if Sai::Decorator.method_defined?(method_name)
767
+ Sai::Decorator.define_method(method_name) { apply_named_color(style_type, color_name) }
758
768
  end
759
769
  end
760
770
 
771
+ Sai::NamedColors.names.each { |color| Sai::Decorator::NamedColors.install(color) }
772
+
761
773
  private
762
774
 
763
775
  # Apply a named color to the specified style type
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sai/conversion/rgb'
4
+
3
5
  module Sai
4
6
  # A collection of named colors and their RGB values
5
7
  #
@@ -406,32 +408,115 @@ module Sai
406
408
  }.freeze #: Hash[Symbol, Array[Integer]]
407
409
  # rubocop:enable Naming/VariableNumber
408
410
 
409
- # Look up an RGB value by color name
410
- #
411
- # @author {https://aaronmallen.me Aaron Allen}
412
- # @since 0.3.1
413
- #
414
- # @api private
415
- #
416
- # @param name [String, Symbol] the color name
417
- #
418
- # @return [Array<Integer>] the RGB value
419
- # @rbs (String | Symbol name) -> Array[Integer]?
420
- def self.[](name)
421
- key = name.to_sym
422
- ANSI.fetch(key, XTERM.fetch(key, CSS.fetch(key, nil)))
423
- end
411
+ class << self
412
+ # Look up an RGB value by color name
413
+ #
414
+ # @author {https://aaronmallen.me Aaron Allen}
415
+ # @since 0.3.1
416
+ #
417
+ # @api private
418
+ #
419
+ # @param name [String, Symbol] the color name
420
+ #
421
+ # @return [Array<Integer>] the RGB value
422
+ # @rbs (String | Symbol name) -> Array[Integer]?
423
+ def [](name)
424
+ registry[name.to_sym]
425
+ end
424
426
 
425
- # Get a list of all color names
426
- #
427
- # @author {https://aaronmallen.me Aaron Allen}
428
- # @since 0.3.1
429
- #
430
- # @api private
431
- #
432
- # @return [Array<Symbol>] the color names
433
- def self.names
434
- (ANSI.keys + CSS.keys + XTERM.keys).uniq.sort
427
+ # Get a list of all color names
428
+ #
429
+ # @author {https://aaronmallen.me Aaron Allen}
430
+ # @since 0.3.1
431
+ #
432
+ # @api private
433
+ #
434
+ # @return [Array<Symbol>] the color names
435
+ def names
436
+ @names ||= registry.keys.uniq.sort
437
+ end
438
+
439
+ # Register a named color with an RGB or Hexadecimal value
440
+ #
441
+ # @author {https://aaronmallen.me Aaron Allen}
442
+ # @since 0.3.2
443
+ #
444
+ # @api private
445
+ #
446
+ # @param name [String, Symbol] the name of the color being registered
447
+ # @param rgb_or_hex [Array<Integer>, String] the RGB or Hexadecimal value of the color
448
+ #
449
+ # @return [Boolean] `true` if the color was registered
450
+ # @rbs (String | Symbol name, Array[Integer] | String rgb_or_hex) -> void
451
+ def register(name, rgb_or_hex)
452
+ key = name.to_s.downcase.to_sym
453
+ provision_color(key, rgb_or_hex)
454
+ install_color(key)
455
+ true
456
+ end
457
+
458
+ private
459
+
460
+ # Install the color methods onto {Sai} and {Sai::Decorator}
461
+ #
462
+ # @author {https://aaronmallen.me Aaron Allen}
463
+ # @since 0.3.2
464
+ #
465
+ # @api private
466
+ #
467
+ # @param name [Symbol] the name of the color to install
468
+ #
469
+ # @return [void]
470
+ # @rbs (Symbol name) -> void
471
+ def install_color(name)
472
+ Sai::Decorator::NamedColors.install(name)
473
+ Sai::Decorator::Delegation.install(Sai)
474
+ end
475
+
476
+ # Provision a color for the registry
477
+ #
478
+ # @author {https://aaronmallen.me Aaron Allen}
479
+ # @since 0.3.2
480
+ #
481
+ # @api private
482
+ #
483
+ # @param name [Symbol] the name of the color to register
484
+ # @param rgb_or_hex [Array<Integer>, String] the RGB or Hexadecimal value of the color
485
+ #
486
+ # @return [void]
487
+ # @rbs (Symbol name, Array[Integer] | String rgb_or_hex) -> void
488
+ def provision_color(name, rgb_or_hex)
489
+ rgb = Conversion::RGB.resolve(rgb_or_hex)
490
+ registry[name] = rgb
491
+ @names = nil
492
+ end
493
+
494
+ # The Sai named colors registry
495
+ #
496
+ # @author {https://aaronmallen.me Aaron Allen}
497
+ # @since 0.3.2
498
+ #
499
+ # @api private
500
+ #
501
+ # @return [Hash{Symbol => Array<Integer>}] the named colors registry
502
+ def registry
503
+ thread_lock.synchronize do
504
+ @registry ||= CSS.merge(XTERM).merge(ANSI)
505
+ end
506
+ end
507
+
508
+ # A Mutex for thread safety
509
+ #
510
+ # @author {https://aaronmallen.me Aaron Allen}
511
+ # @since 0.3.2
512
+ #
513
+ # @api private
514
+ #
515
+ # @return [Mutex] the thread lock
516
+ # @rbs () -> Mutex
517
+ def thread_lock
518
+ @thread_lock ||= Mutex.new
519
+ end
435
520
  end
436
521
  end
437
522
  end
data/lib/sai.rb CHANGED
@@ -833,6 +833,28 @@ module Sai
833
833
  ModeSelector
834
834
  end
835
835
 
836
+ # Register a custom name and color
837
+ #
838
+ # @author {https://aaronmallen.me Aaron Allen}
839
+ # @since 0.3.2
840
+ #
841
+ # @api public
842
+ #
843
+ # @example Register a color
844
+ # Sai.register(:my_color, '#CF4C5F')
845
+ # Sai.register(:my_color, [207, 76, 95])
846
+ #
847
+ # Sai.my_color.decorate('Hello, world!').to_s #=> "\e[38;2;207;76;95mHello, world!\e[0m"
848
+ #
849
+ # @param name [String, Symbol] the name of the color to register
850
+ # @param rgb_or_hex [Array<Integer>, String] the RGB values or hex code to register
851
+ #
852
+ # @return [void]
853
+ # @rbs (String | Symbol name, Array[Integer] | String rgb_or_hex) -> void
854
+ def register(name, rgb_or_hex)
855
+ NamedColors.register(name, rgb_or_hex)
856
+ end
857
+
836
858
  # Sequence a string with ANSI escape codes
837
859
  #
838
860
  # @author {https://aaronmallen.me Aaron Allen}
@@ -1471,6 +1471,19 @@ module Sai
1471
1471
 
1472
1472
  def yellow_system: () -> Decorator
1473
1473
 
1474
+ # Install a color method on the {Decorator} class
1475
+ #
1476
+ # @author {https://aaronmallen.me Aaron Allen}
1477
+ # @since 0.3.2
1478
+ #
1479
+ # @api private
1480
+ #
1481
+ # @param color_name [Symbol] the name of the color to install
1482
+ #
1483
+ # @return [void]
1484
+ # @rbs (Symbol color_name) -> void
1485
+ def self.install: (Symbol color_name) -> void
1486
+
1474
1487
  private
1475
1488
 
1476
1489
  # Apply a named color to the specified style type
@@ -61,5 +61,67 @@ module Sai
61
61
  #
62
62
  # @return [Array<Symbol>] the color names
63
63
  def self.names: () -> untyped
64
+
65
+ # Register a named color with an RGB or Hexadecimal value
66
+ #
67
+ # @author {https://aaronmallen.me Aaron Allen}
68
+ # @since 0.3.2
69
+ #
70
+ # @api private
71
+ #
72
+ # @param name [String, Symbol] the name of the color being registered
73
+ # @param rgb_or_hex [Array<Integer>, String] the RGB or Hexadecimal value of the color
74
+ #
75
+ # @return [Boolean] `true` if the color was registered
76
+ # @rbs (String | Symbol name, Array[Integer] | String rgb_or_hex) -> void
77
+ def self.register: (String | Symbol name, Array[Integer] | String rgb_or_hex) -> void
78
+
79
+ # Install the color methods onto {Sai} and {Sai::Decorator}
80
+ #
81
+ # @author {https://aaronmallen.me Aaron Allen}
82
+ # @since 0.3.2
83
+ #
84
+ # @api private
85
+ #
86
+ # @param name [Symbol] the name of the color to install
87
+ #
88
+ # @return [void]
89
+ # @rbs (Symbol name) -> void
90
+ private def self.install_color: (Symbol name) -> void
91
+
92
+ # Provision a color for the registry
93
+ #
94
+ # @author {https://aaronmallen.me Aaron Allen}
95
+ # @since 0.3.2
96
+ #
97
+ # @api private
98
+ #
99
+ # @param name [Symbol] the name of the color to register
100
+ # @param rgb_or_hex [Array<Integer>, String] the RGB or Hexadecimal value of the color
101
+ #
102
+ # @return [void]
103
+ # @rbs (Symbol name, Array[Integer] | String rgb_or_hex) -> void
104
+ private def self.provision_color: (Symbol name, Array[Integer] | String rgb_or_hex) -> void
105
+
106
+ # The Sai named colors registry
107
+ #
108
+ # @author {https://aaronmallen.me Aaron Allen}
109
+ # @since 0.3.2
110
+ #
111
+ # @api private
112
+ #
113
+ # @return [Hash{Symbol => Array<Integer>}] the named colors registry
114
+ private def self.registry: () -> untyped
115
+
116
+ # A Mutex for thread safety
117
+ #
118
+ # @author {https://aaronmallen.me Aaron Allen}
119
+ # @since 0.3.2
120
+ #
121
+ # @api private
122
+ #
123
+ # @return [Mutex] the thread lock
124
+ # @rbs () -> Mutex
125
+ private def self.thread_lock: () -> Mutex
64
126
  end
65
127
  end
data/sig/sai.rbs CHANGED
@@ -1574,6 +1574,26 @@ module Sai
1574
1574
  # @rbs () -> singleton(ModeSelector)
1575
1575
  def self.mode: () -> singleton(ModeSelector)
1576
1576
 
1577
+ # Register a custom name and color
1578
+ #
1579
+ # @author {https://aaronmallen.me Aaron Allen}
1580
+ # @since 0.3.2
1581
+ #
1582
+ # @api public
1583
+ #
1584
+ # @example Register a color
1585
+ # Sai.register(:my_color, '#CF4C5F')
1586
+ # Sai.register(:my_color, [207, 76, 95])
1587
+ #
1588
+ # Sai.my_color.decorate('Hello, world!').to_s #=> "\e[38;2;207;76;95mHello, world!\e[0m"
1589
+ #
1590
+ # @param name [String, Symbol] the name of the color to register
1591
+ # @param rgb_or_hex [Array<Integer>, String] the RGB values or hex code to register
1592
+ #
1593
+ # @return [void]
1594
+ # @rbs (String | Symbol name, Array[Integer] | String rgb_or_hex) -> void
1595
+ def self.register: (String | Symbol name, Array[Integer] | String rgb_or_hex) -> void
1596
+
1577
1597
  # Sequence a string with ANSI escape codes
1578
1598
  #
1579
1599
  # @author {https://aaronmallen.me Aaron Allen}
metadata CHANGED
@@ -1,10 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Allen
8
+ autorequire:
8
9
  bindir: bin
9
10
  cert_chain: []
10
11
  date: 2025-01-22 00:00:00.000000000 Z
@@ -79,10 +80,11 @@ licenses:
79
80
  - MIT
80
81
  metadata:
81
82
  bug_tracker_uri: https://github.com/aaronmallen/sai/issues
82
- changelog_uri: https://github.com/aaronmallen/sai/releases/tag/0.3.1
83
+ changelog_uri: https://github.com/aaronmallen/sai/releases/tag/0.3.2
83
84
  homepage_uri: https://github.com/aaronmallen/sai
84
85
  rubygems_mfa_required: 'true'
85
- source_code_uri: https://github.com/aaronmallen/sai/tree/0.3.1
86
+ source_code_uri: https://github.com/aaronmallen/sai/tree/0.3.2
87
+ post_install_message:
86
88
  rdoc_options: []
87
89
  require_paths:
88
90
  - lib
@@ -97,7 +99,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
97
99
  - !ruby/object:Gem::Version
98
100
  version: '0'
99
101
  requirements: []
100
- rubygems_version: 3.6.2
102
+ rubygems_version: 3.3.27
103
+ signing_key:
101
104
  specification_version: 4
102
105
  summary: An elegant color management system for crafting sophisticated CLI applications
103
106
  test_files: []