ex_aequo 0.2.6 → 0.3.1

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,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './colorize/color_definitions'
4
+
5
+ module ExAequo
6
+ module Colorizer extend self
7
+
8
+ def colorize(line, reset: false)
9
+ line = line.chomp
10
+ no_color = ENV.fetch('NO_COLOR', false)
11
+ case parse(line.grapheme_clusters, no_color)
12
+ in {ok: true, result:}
13
+ {ok: true, result: join_result(result, no_color:, reset:)}
14
+ in error
15
+ error
16
+ end
17
+ end
18
+
19
+ def colorize_file(file, reset: false)
20
+ file = File.open(file, 'r') if String === file
21
+
22
+ at_exit do
23
+ file.close rescue nil
24
+ end
25
+ colorize_lines( file.readlines(chomp: true) )
26
+ end
27
+
28
+ def colorize_lines(lines, reset: false)
29
+ lines = lines.split(%r{\n\r?}) if String === lines
30
+ lines
31
+ .each_with_index do | line, idx |
32
+ case colorize(line, reset:)
33
+ in {ok: true, result:}
34
+ puts result
35
+ in {ok: false, error:}
36
+ $stderr.puts("ERROR in line #{idx.succ} ** #{error} **")
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def app(ary, ary_or_elem)
44
+ case ary_or_elem
45
+ when Array
46
+ [*ary, *ary_or_elem]
47
+ else
48
+ [*ary, ary_or_elem]
49
+ end
50
+ end
51
+
52
+ def check_color_definition(rest, no_color,color)
53
+ case ColorDefinitions.get(color, no_color)
54
+ in nil
55
+ {ok: false, error: "undefined color #{color}"}
56
+ in color
57
+ {ok: true, color:}
58
+ end
59
+ end
60
+
61
+ def get_color!(color, no_color)
62
+ case ColorDefinitions.get(color, no_color)
63
+ in nil
64
+ raise "This should not have happened"
65
+ in color
66
+ color
67
+ end
68
+ end
69
+
70
+ def join_result(result, no_color:, reset:)
71
+ app(result, reset ? get_color!(:reset, no_color) : '')
72
+ .join
73
+ end
74
+
75
+ def parse(line, no_color, result = [])
76
+ # p(line:, result:)
77
+ case line
78
+ in []
79
+ {ok: true, result:}
80
+ in ['<', '<', *rest]
81
+ parse(rest, no_color, app(result, '<'))
82
+ in ['$', '$', *rest]
83
+ parse(rest, no_color, app(result, '$'))
84
+ in ['$', *rest]
85
+ parse(rest, no_color, app(result, reset(no_color)))
86
+ in ['<', *rest]
87
+ parse_color(rest, no_color, result)
88
+ in [char, *rest]
89
+ parse(rest, no_color, app(result, char))
90
+ end
91
+ end
92
+
93
+ def parse_color(line, no_color, result, color=[])
94
+ # p(line:line, result:, color:)
95
+ case line
96
+ in []
97
+ {ok: false, error: "Incomplete Color Spec #{color.join}"}
98
+ in ['>', *rest]
99
+ parse_continue_after_color(rest, no_color, result, color.join)
100
+ in [',', *rest]
101
+ parse_next_color(rest, no_color, result, color.join)
102
+ in [char, *rest]
103
+ parse_color(rest, no_color, result, app(color, char))
104
+ end
105
+ end
106
+
107
+ def parse_continue_after_color(rest, no_color, result, color)
108
+ case check_color_definition(rest, no_color, color)
109
+ in {ok: true, color:}
110
+ parse(rest, no_color, app(result, color))
111
+ in error
112
+ error
113
+ end
114
+ end
115
+
116
+ def parse_next_color(rest, no_color, result, color)
117
+ case check_color_definition(rest, no_color, color)
118
+ in {ok: true, color:}
119
+ parse_color(rest, no_color, app(result, color))
120
+ in error
121
+ error
122
+ end
123
+ end
124
+
125
+ def reset(no_color)
126
+ get_color!(:reset, no_color)
127
+ end
128
+ end
129
+ end
130
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enumerable
4
+ def find_value(&block)
5
+ each do |ele|
6
+ case block.(ele)
7
+ in nil
8
+ nil
9
+ in false
10
+ false
11
+ in value
12
+ return value
13
+ end
14
+ end
15
+ nil
16
+ end
17
+ end
18
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -5,5 +5,8 @@ module Fn
5
5
  def prefix_string(with)
6
6
  ->(subject) { "#{with}#{subject}" }
7
7
  end
8
+ def split_string(by=/\s+/)
9
+ ->(subject) {subject.split(by)}
10
+ end
8
11
  end
9
12
  # SPDX-License-Identifier: Apache-2.0
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MatchData
4
+ def deconstruct(*) = to_a
5
+ end
6
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'ostruct'
3
4
  class MyStruct < OpenStruct
4
5
  module ClassMethods
5
6
  def from_reduce(keys, acc, &reducer)
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'io/console'
4
+ require_relative '../colorize'
5
+ module ExAequo
6
+ module Ui
7
+ module Prompts extend self
8
+ extend Colorize
9
+
10
+ def prompt_ch(text: nil, chars:)
11
+ loop do
12
+ $stdout.print(text || _mk_text(chars))
13
+ $stdout.flush
14
+ case _member($stdin.getch, chars)
15
+ in {ok: true, ch:}
16
+ return ch
17
+ in {ok: false, ch:}
18
+ $stdout.puts(colorize("<red>ERROR$: Illegal char entered -> #{ch.inspect}"))
19
+ end
20
+ end
21
+ end
22
+
23
+ private
24
+ def _keys_or_members(chars)
25
+ case chars
26
+ when Hash
27
+ chars.keys
28
+ else
29
+ chars.to_a
30
+ end
31
+ .join(', ')
32
+ end
33
+
34
+ def _member(ch, chars)
35
+ if chars.member?(ch)
36
+ {ok: true, ch: ch}
37
+ else
38
+ {ok: false, ch: ch}
39
+ end
40
+ end
41
+
42
+ def _mk_text(chars)
43
+ "Please enter one of the following chars #{_keys_or_members(chars)} > "
44
+ end
45
+ end
46
+ end
47
+ end
48
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ui/prompts'
4
+ module ExAequo
5
+ module Ui
6
+ extend Forwardable
7
+ def_delegators Prompts, :prompt_ch
8
+ end
9
+ end
10
+ # SPDX-License-Identifier: AGPL-3.0-or-later
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ExAequo
4
4
  module Version
5
- VERSION = '0.2.6'
5
+ VERSION = '0.3.1'
6
6
  end
7
7
  end
8
8
  # SPDX-License-Identifier: Apache-2.0
data/lib/ex_aequo.rb CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  module ExAequo
4
4
  end
5
+ require 'ostruct'
5
6
  require_relative 'ex_aequo/args_parser'
6
- require_relative 'ex_aequo/color'
7
7
  require_relative 'ex_aequo/version'
8
8
  # SPDX-License-Identifier: Apache-2.0
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ex_aequo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Dober
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-04-07 00:00:00.000000000 Z
11
+ date: 2024-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: forwarder3
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.1.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: ostruct
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  description: 'Some tools
28
42
 
29
43
  '
@@ -37,21 +51,19 @@ files:
37
51
  - lib/ex_aequo.rb
38
52
  - lib/ex_aequo/args.rb
39
53
  - lib/ex_aequo/args_parser.rb
40
- - lib/ex_aequo/color.rb
41
- - lib/ex_aequo/color/ansi.rb
42
- - lib/ex_aequo/color/ansi256.rb
43
- - lib/ex_aequo/color/colorizer.rb
44
- - lib/ex_aequo/color/modifiers.rb
45
- - lib/ex_aequo/color/rgb.rb
46
- - lib/ex_aequo/color/text.rb
47
- - lib/ex_aequo/color/web.rb
48
- - lib/ex_aequo/colors.rb
54
+ - lib/ex_aequo/colorize.rb
55
+ - lib/ex_aequo/colorize/color_definitions.rb
56
+ - lib/ex_aequo/colorizer.rb
49
57
  - lib/ex_aequo/kernel.rb
50
58
  - lib/ex_aequo/kernel/access.rb
59
+ - lib/ex_aequo/kernel/enumerable.rb
51
60
  - lib/ex_aequo/kernel/fn.rb
61
+ - lib/ex_aequo/kernel/match_data.rb
52
62
  - lib/ex_aequo/my_struct.rb
53
63
  - lib/ex_aequo/my_struct/class_methods.rb
54
64
  - lib/ex_aequo/tools/text_scanner.rb
65
+ - lib/ex_aequo/ui.rb
66
+ - lib/ex_aequo/ui/prompts.rb
55
67
  - lib/ex_aequo/version.rb
56
68
  homepage: https://gitlab.com/robert_dober/rb_ex_aequo
57
69
  licenses:
@@ -65,14 +77,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
77
  requirements:
66
78
  - - ">="
67
79
  - !ruby/object:Gem::Version
68
- version: 3.1.0
80
+ version: 3.3.0
69
81
  required_rubygems_version: !ruby/object:Gem::Requirement
70
82
  requirements:
71
83
  - - ">="
72
84
  - !ruby/object:Gem::Version
73
85
  version: '0'
74
86
  requirements: []
75
- rubygems_version: 3.3.26
87
+ rubygems_version: 3.5.16
76
88
  signing_key:
77
89
  specification_version: 4
78
90
  summary: Some tools
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'modifiers'
4
- module ExAequo
5
- module Color
6
- module Ansi
7
- extend self
8
- include ExAequo::Color::Modifiers
9
-
10
- AnsiColorEscape = {
11
- black: 30,
12
- red: 31,
13
- green: 32,
14
- yellow: 33,
15
- blue: 34,
16
- magenta: 35,
17
- cyan: 36,
18
- white: 37
19
- }.freeze
20
-
21
- def ansi(name, bold: false, dim: false, italic: false, underline: false)
22
- case AnsiColorEscape.fetch(name.to_s.downcase.to_sym, nil)
23
- in nil
24
- raise IllegalColor, "#{name} is not one of the 8 legal basic ansi color names: #{_legal_ansi_color_names}"
25
- in value
26
- "\e[#{value}#{postfix_modifiers(bold:, dim:, italic:, underline:)}m"
27
- end
28
- end
29
-
30
- private
31
-
32
- def _legal_ansi_color_names
33
- AnsiColorEscape.keys.inspect
34
- end
35
- end
36
- end
37
- end
38
- # SPDX-License-Identifier: Apache-2.0
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'modifiers'
4
- module ExAequo
5
- module Color
6
- module Ansi256
7
- extend self
8
- include ExAequo::Color::Modifiers
9
-
10
- def ansi256(color, bold: false, dim: false, italic: false, underline: false)
11
- case color
12
- in 0..255
13
- "\e[38;5;#{color}#{postfix_modifiers(bold:, dim:, italic:, underline:)}m"
14
- else
15
- raise IllegalColor, "#{color.inspect} is not a color number between 0 and 255"
16
- end
17
- end
18
- end
19
- end
20
- end
21
- # SPDX-License-Identifier: Apache-2.0
@@ -1,76 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ExAequo
4
- module Color
5
- module Colorizer
6
- extend self
7
-
8
- ColorMethodKeywords = {
9
- ansi: nil,
10
- ansi256: nil,
11
- rgb: nil,
12
- web: nil
13
- }.freeze
14
-
15
- StyleKeywords = {
16
- bold: nil,
17
- dim: nil,
18
- italic: nil,
19
- underline: nil
20
- }.freeze
21
-
22
- ColorizeKeywords = ColorMethodKeywords.merge(StyleKeywords).merge(reset: true)
23
-
24
- def colorize(text, **kwds)
25
- kwds = ColorizeKeywords.merge(kwds)
26
- _check_args!(kwds)
27
-
28
- [
29
- _color_code(**kwds),
30
- text,
31
- _maybe_reset(kwds[:reset])
32
- ].join
33
- end
34
-
35
- private
36
-
37
- def _check_args!(kwds)
38
- spurious = kwds.keys - ColorizeKeywords.keys
39
- raise ArgumentError, "illegal keywords #{spurious}, allowed: #{ColorizeKeywords.keys}" unless spurious.empty?
40
-
41
- _check_rgb_args!(kwds)
42
- end
43
-
44
- def _check_rgb_args!(kwds)
45
- unless kwds.values_at(*ColorMethodKeywords.keys).compact.size == 1
46
- raise ArgumentError, 'need to specify exactly one of the following keyword arguments: :ansi, :ansi256, :rgb, :web'
47
- end
48
-
49
- if kwds[:rgb] && Access.any_key?(kwds, :bold, :dim)
50
- raise(
51
- ArgumentError,
52
- 'specifying bold and/or dim with rgb does not make sense'
53
- )
54
- end
55
- end
56
-
57
- def _color_code(**kwds)
58
- kwds => {ansi:, ansi256:, rgb:, web:, italic:, underline:}
59
- if rgb
60
- ExAequo::Color.rgb(*Array(rgb), italic:, underline:)
61
- elsif web
62
- ExAequo::Color.rgb(*ExAequo::Color::Web.to_rgb(web), italic:, underline:)
63
- elsif ansi
64
- ExAequo::Color.ansi(ansi, **kwds.slice(*StyleKeywords.keys))
65
- else
66
- ExAequo::Color.ansi256(ansi256, **kwds.slice(*StyleKeywords.keys))
67
- end
68
- end
69
-
70
- def _maybe_reset(reset)
71
- reset ? ExAequo::Color.reset : nil
72
- end
73
- end
74
- end
75
- end
76
- # SPDX-License-Identifier: Apache-2.0
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module ExAequo
4
- module Color
5
- module Modifiers extend self
6
- ModifierValues = {
7
- bold: 1,
8
- dim: 2,
9
- italic: 3,
10
- underline: 4
11
- }.freeze
12
-
13
- def postfix_modifiers(bold: nil, dim: nil, italic: nil, underline: nil)
14
- [
15
- bold ? :bold : nil,
16
- dim ? :dim : nil,
17
- italic ? :italic : nil,
18
- underline ? :underline : nil
19
- ].compact
20
- .map(&Access.hash_by_key(ModifierValues))
21
- .map(&Fn.prefix_string(';'))
22
- .join
23
- end
24
- end
25
- end
26
- end
27
- # SPDX-License-Identifier: Apache-2.0
@@ -1,63 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'modifiers'
4
- module ExAequo
5
- module Color
6
- module Rgb
7
- extend self
8
-
9
- def rgb(red, green = nil, blue = nil, **kwds)
10
- if green && blue
11
- _rgb(red, green, blue, **kwds)
12
- else
13
- raise ArgumentError, 'takes 1 or 3 parameters, given two' if green
14
-
15
- _rgb(*_hex_to_triple(red), **kwds)
16
- end
17
- end
18
-
19
- private
20
-
21
- def _check_rgb(red, green, blue)
22
- if _check_rgb_byte(red) && _check_rgb_byte(green) && _check_rgb_byte(blue)
23
- :ok
24
- else
25
- "#{[red, green, blue]} is not a legal rgb specification, need three bytes (0..255)"
26
- end
27
- end
28
-
29
- def _check_rgb_byte(byte)
30
- case byte
31
- in 0..255
32
- true
33
- else
34
- false
35
- end
36
- end
37
-
38
- LeadingHashRgx = %r{\A#}
39
- def _hex_to_triple(hex)
40
- chex = hex.sub(LeadingHashRgx, '')
41
- case chex.grapheme_clusters.each_slice(2).map(&:join).map { Integer(_1, 16) }
42
- in r, g, b
43
- [r, g, b]
44
- else
45
- raise IllegalColor, "#{hex} is not a legal rgb hex string"
46
- end
47
- rescue ArgumentError
48
- raise IllegalColor, "#{hex} is not a legal rgb hex string"
49
- end
50
-
51
- def _rgb(red, green, blue, italic: false, underline: false)
52
- case _check_rgb(red, green, blue)
53
- in :ok
54
- modifier = ExAequo::Color::Modifiers.postfix_modifiers(italic:, underline:)
55
- "\e[38;2;#{red};#{green};#{blue}#{modifier}m"
56
- in message
57
- raise IllegalColor, message
58
- end
59
- end
60
- end
61
- end
62
- end
63
- # SPDX-License-Identifier: Apache-2.0
@@ -1,51 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../color'
4
- module ExAequo
5
- module Color
6
-
7
- module Text extend self
8
- Specials = {
9
- bold: ExAequo::Color::Ansi.ansi(:white, bold: true),
10
- eol: "\n",
11
- reset: ExAequo::Color.reset
12
- }
13
-
14
- def put_col(*segments, to: $stdout)
15
- to.puts(colorized_text(segments))
16
- end
17
-
18
- def colorized_text(*segments)
19
- if ENV['NO_COLOR']
20
- segments.flatten.filter { String === _1 }.join
21
- else
22
- segments.flatten.map(&_color_or_text).join
23
- end
24
- end
25
-
26
- private
27
-
28
-
29
- def _color_or_text
30
- -> color_or_text do
31
- case color_or_text
32
- when Symbol
33
- _colorize(color_or_text)
34
- else
35
- color_or_text
36
- end
37
- end
38
- end
39
-
40
- def _colorize(color)
41
- case ExAequo::Color::Ansi::AnsiColorEscape[color]
42
- when nil
43
- Specials.fetch(color) { raise ArgumentError, "#{color} not yet implemented" }
44
- else
45
- ExAequo::Color::Ansi.ansi(color)
46
- end
47
- end
48
- end
49
- end
50
- end
51
- # SPDX-License-Identifier: Apache-2.0