ex_aequo_color 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.
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExAequo
4
+ module Color
5
+ SyntaxError = Class.new(RuntimeError)
6
+
7
+ module Colorizer extend self
8
+ def colorize(line, reset: false)
9
+ line = line.chomp
10
+ no_color = ENV.fetch('NO_COLOR', false)
11
+ result = parse(line.grapheme_clusters, no_color)
12
+ case result
13
+ in {ok: true, result:}
14
+ Result.ok(join_result(result, no_color:, reset:))
15
+ else
16
+ result
17
+ end
18
+ end
19
+
20
+ def colorize!(line, reset: false)
21
+ case colorize(line, reset:)
22
+ in {ok: true, result:}
23
+ result
24
+ in {ok: false, error:}
25
+ raise SyntaxError, error
26
+ else
27
+ end
28
+ end
29
+
30
+ def colorize_file(file, device: $stdout, reset: false)
31
+ file = File.open(file, 'r') if String === file
32
+
33
+ at_exit do
34
+ file.close rescue nil
35
+ end
36
+ colorize_lines(file.readlines(chomp: true), device:, reset:)
37
+ end
38
+
39
+ def colorize_lines(lines, reset: false, device: $stdout)
40
+ lines = lines.split(%r{\n\r?}) if String === lines
41
+ lines
42
+ .each_with_index do | line, idx |
43
+ result = colorize(line, reset:).extract { |r|
44
+ $stderr.puts("ERROR in line #{idx.succ} ** #{r.error} **")
45
+ }
46
+ device.puts result
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def app(ary, ary_or_elem)
53
+ case ary_or_elem
54
+ when Array
55
+ [*ary, *ary_or_elem]
56
+ else
57
+ [*ary, ary_or_elem]
58
+ end
59
+ end
60
+
61
+ def check_color_definition(rest, no_color,color)
62
+ colored = ColorDefinitions.get(color, no_color)
63
+ Result.from_value colored, error: "undefined color #{color}"
64
+ end
65
+
66
+ def get_color!(color, no_color)
67
+ color_def = ColorDefinitions.get(color, no_color)
68
+ return color_def if color_def
69
+
70
+ raise "Bad color definition #{color.inspect}"
71
+ end
72
+
73
+ def join_result(result, no_color:, reset:)
74
+ app(result, reset ? get_color!(:reset, no_color) : '')
75
+ .join
76
+ end
77
+
78
+ def parse(line, no_color, result = [])
79
+ case line
80
+ in []
81
+ Result.ok(result)
82
+ in ['<', '<', *rest]
83
+ parse(rest, no_color, app(result, '<'))
84
+ in ['$', '$', *rest]
85
+ parse(rest, no_color, app(result, '$'))
86
+ in ['$', *rest]
87
+ parse(rest, no_color, app(result, reset(no_color)))
88
+ in ['<', *rest]
89
+ parse_color(rest, no_color, result)
90
+ else
91
+ parse(line.drop(1), no_color, app(result, line.first))
92
+ end
93
+ end
94
+
95
+ def parse_color(line, no_color, result, color=[])
96
+ case line
97
+ in []
98
+ Result.nok("Incomplete Color Spec #{color.join}")
99
+ in ['>', *rest]
100
+ parse_continue_after_color(rest, no_color, result, color.join)
101
+ in [',', *rest]
102
+ parse_next_color(rest, no_color, result, color.join)
103
+ else
104
+ parse_color(line.drop(1), no_color, result, app(color, line.first))
105
+ end
106
+ end
107
+
108
+ def parse_continue_after_color(rest, no_color, result, color)
109
+ checked = check_color_definition(rest, no_color, color)
110
+ case checked
111
+ in {ok: true, result: color}
112
+ parse(rest, no_color, app(result, color))
113
+ else
114
+ checked
115
+ end
116
+ end
117
+
118
+ def parse_next_color(rest, no_color, result, color)
119
+ color_def = check_color_definition(rest, no_color, color)
120
+ case color_def
121
+ in {ok: true, result: color}
122
+ parse_color(rest, no_color, app(result, color))
123
+ else
124
+ color_def
125
+ end
126
+ end
127
+
128
+ def reset(no_color)
129
+ get_color!(:reset, no_color)
130
+ end
131
+ end
132
+ end
133
+ end
134
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ExAequo
4
+ module Color
5
+ module Encode extend self
6
+
7
+ def color(*chunks, reset: true)
8
+ _colors(chunks.flatten) => {needs_reset:, colorized:}
9
+ colorized << _color_code(:reset) if needs_reset && reset
10
+
11
+ colorized.join
12
+ end
13
+
14
+ def sgc(value)
15
+ return '' if _no_color
16
+
17
+ ColorDefinitions.sgc(value)
18
+ end
19
+
20
+ private
21
+ def _colors(chunks) =
22
+ # need the [""] to get the correct encoding (WTH?)
23
+ chunks.inject(OpenStruct.new(needs_reset: false, colorized: [""])) do |acc, chunk|
24
+ _color(acc, chunk)
25
+ end
26
+
27
+ def _color(acc, chunk)
28
+ case chunk
29
+ when Symbol
30
+ acc.colorized << _color_code(chunk)
31
+ acc.update(needs_reset: chunk != :reset)
32
+ when String
33
+ acc.colorized << chunk
34
+ when 0
35
+ acc.colorized << _color_code(:reset)
36
+ acc.update(needs_reset: false)
37
+ else
38
+ raise ArgumentError, "need a colorspec by symbol, a string or 0 (short for :reset), but got #{chunk.inspect}"
39
+ end
40
+ acc
41
+ end
42
+
43
+ def _color_code(color) =
44
+ ColorDefinitions.get(color, _no_color).tap do
45
+ raise BadColorSpecification, "bad color specification: #{color}" unless it
46
+ end
47
+
48
+ def _no_color
49
+ @___no_color__ ||= ENV['NO_COLOR']
50
+ end
51
+
52
+ end
53
+ end
54
+ end
55
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'encode'
4
+ module ExAequo
5
+ module Color
6
+ module Output extend self
7
+
8
+ def putc(*chunks, reset: false, device: $stdout)
9
+ output = Encode.color(*chunks, reset:)
10
+ device.print(output)
11
+ end
12
+
13
+ def putcs(*chunks, reset: true, device: $stdout)
14
+ output = Encode.color(*chunks, reset:)
15
+ device.puts(output)
16
+ end
17
+
18
+ end
19
+ end
20
+ end
21
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class String
4
+ def colored(color, reset: true)
5
+ Color.color(color, self, reset:)
6
+ end
7
+
8
+ def pcolored(color, reset: true, device: $stdout) = Color.pcolored(color, self, reset:, device:)
9
+ end
10
+ # SPDX-License-Identifier: AGPL-3.0-or-later
11
+
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ExAequo
4
4
  module Color
5
- VERSION = '0.1.0'
5
+ VERSION = '0.2.0'
6
6
  end
7
7
  end
8
8
  # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -1,41 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'colorizer'
3
+ require 'ex_aequo/base/result/import'
4
+
5
+ require_relative 'color/color_definitions'
6
+ require_relative 'color/colorizer'
7
+ require_relative 'color/output'
4
8
  require 'forwardable'
9
+ require_relative 'ostruct'
5
10
  module ExAequo
6
11
  module Color extend self
7
- extend Forwardable
8
-
9
- def_delegators Colorizer, :colorize, :colorize_file, :colorize_lines
10
-
11
- def color(*chunks, reset: true)
12
- colorized = _colors(chunks.flatten)
13
- return colorized unless reset
12
+ BadColorSpecification = Class.new(RuntimeError)
13
+ extend Encode
14
+ extend Output
14
15
 
15
- colorized + _colors([0])
16
+ def self.included(into)
17
+ into.send(:include, Encode)
18
+ into.send(:include, Output)
16
19
  end
17
20
 
18
- private
19
- def _colors(chunks) = chunks.map { _color it }.join
20
-
21
- def _color(chunk)
22
- case chunk
23
- when Symbol
24
- _get_color(chunk)
25
- when String
26
- chunk
27
- when 0
28
- _get_color(:reset)
29
- else
30
- raise ArgumentError, "need a colorspec by symbol, a string or 0 (short for :reset)"
31
- end
32
- end
33
-
34
- def _get_color(color) = Colorizer::ColorDefinitions.get(color, _no_color)
21
+ extend Forwardable
22
+ def_delegators Colorizer, :colorize, :colorize!, :colorize_file, :colorize_lines
35
23
 
36
- def _no_color
37
- @___no_color__ ||= ENV['NO_COLOR']
38
- end
24
+ def pcolored(*chunks, reset: true, device: $stderr) = device.puts(color(*chunks, reset:))
39
25
  end
40
26
  end
41
27
  # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ostruct'
4
+ class OpenStruct
5
+ def deconstruct_keys(*) = to_h
6
+
7
+ def update(**opts)
8
+ opts.each do |k, v|
9
+ self[k] = v
10
+ end
11
+ end
12
+ end
13
+ # SPDX-License-Identifier: AGPL-3.0-or-later
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ex_aequo_color
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Dober
@@ -10,19 +10,19 @@ cert_chain: []
10
10
  date: 1980-01-02 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
- name: ostruct
13
+ name: ex_aequo_base
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 0.6.1
18
+ version: 0.3.5
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 0.6.1
25
+ version: 0.3.5
26
26
  description: Rainbows in your shell
27
27
  email: robert.dober@gmail.com
28
28
  executables: []
@@ -31,11 +31,16 @@ extra_rdoc_files: []
31
31
  files:
32
32
  - LICENSE
33
33
  - README.md
34
- - lib/ex_aequo.rb
35
34
  - lib/ex_aequo/color.rb
35
+ - lib/ex_aequo/color/all.rb
36
+ - lib/ex_aequo/color/ansi_color_names.rb
37
+ - lib/ex_aequo/color/color_definitions.rb
38
+ - lib/ex_aequo/color/colorizer.rb
39
+ - lib/ex_aequo/color/encode.rb
40
+ - lib/ex_aequo/color/output.rb
41
+ - lib/ex_aequo/color/string.rb
36
42
  - lib/ex_aequo/color/version.rb
37
- - lib/ex_aequo/colorize/color_definitions.rb
38
- - lib/ex_aequo/colorizer.rb
43
+ - lib/ex_aequo/ostruct.rb
39
44
  homepage: https://codeberg.org/lab419/rb_ex_aequo_color.git
40
45
  licenses:
41
46
  - AGPL-3.0-or-later
@@ -47,14 +52,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
47
52
  requirements:
48
53
  - - ">="
49
54
  - !ruby/object:Gem::Version
50
- version: 3.4.1
55
+ version: 3.4.5
51
56
  required_rubygems_version: !ruby/object:Gem::Requirement
52
57
  requirements:
53
58
  - - ">="
54
59
  - !ruby/object:Gem::Version
55
60
  version: '0'
56
61
  requirements: []
57
- rubygems_version: 3.6.8
62
+ rubygems_version: 3.7.1
58
63
  specification_version: 4
59
64
  summary: Rainbows in your shell
60
65
  test_files: []