ex_aequo 0.2.6 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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