mp-utils 0.3.1 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 472fb772fc669be45aee52e5f931823934e59cb5f36974536dbfea782024ac9d
4
- data.tar.gz: 9c5079304a471c97261ec621457575b1b79c9454a8a60f7d19ee9b0a51a7c777
3
+ metadata.gz: 0a57051627a8e74a98a9209b1c213c6148846cf4fe0f4a7a1da5e0b8dbc64cd7
4
+ data.tar.gz: bd146f3f15a46dbab724a0b18878842a9d96c1508feec23dcf7c9da9b7c99de8
5
5
  SHA512:
6
- metadata.gz: 79864c2f162bb4d136ae0762d4196c868e0ce4136a31bb873ce79289478734f442acfc18e882d942b53b15e26c570a8b4d18c144f88d1ceae4573c01121583d8
7
- data.tar.gz: cd1ed6a8fdb3c724d1953c0df5107468936b5a4800b537097ca32d3f134123c93f39c45ee327a347037e6246fe23600030128fe12f7371034d11bca9fb347204
6
+ metadata.gz: 8a3c24a403c587a815a14e9ffd7e9321a1642eee43ea96c1282199f7d25c38a403206e277be6855c488a366f96f9eff7f8c823956458ca2e85d09bb4d97abe4b
7
+ data.tar.gz: c41ceaf522f2d4d9b56de23e432910eeae65697fdf98080755c4d46523486caf8b9226f7eeac2a9220642125b708d1b4ee1d98d9b2b6c22fd2488010ce080e5b
data/lib/mp_utils.rb CHANGED
@@ -3,8 +3,10 @@
3
3
  require_relative 'utils/key'
4
4
  require_relative 'utils/ansi'
5
5
  require_relative 'utils/array'
6
+ require_relative 'utils/string'
6
7
  require_relative 'utils/message'
7
8
  require_relative 'utils/question'
8
9
  require_relative 'utils/version_manager'
9
10
  require_relative 'utils/ansi_style_manager'
11
+ require_relative 'utils/directory_structure'
10
12
  require_relative 'resources/path_helper'
data/lib/utils/ansi.rb CHANGED
@@ -2,18 +2,18 @@
2
2
 
3
3
  require_relative 'constants'
4
4
 
5
- # The ANSI class is responsible for generating ANSI codes for text styling in terminals.
6
- # It allows the combination of multiple style and color codes.
5
+ # The ANSI class is responsible for generating ANSI codes for text styling in terminals.
6
+ # It allows the combination of multiple style and color codes.
7
7
  #
8
- # @example
9
- # ansi = ANSI.new(:bold)
10
- # puts ansi.to_s # => "\e[1m"
8
+ # @example
9
+ # ansi = ANSI.new(:bold)
10
+ # puts ansi.to_s # => "\e[1m"
11
11
  #
12
- # @example
13
- # ansi = ANSI.new([:bold, :red])
14
- # puts ansi.to_s # => "\e[1;31m"
12
+ # @example
13
+ # ansi = ANSI.new([:bold, :red])
14
+ # puts ansi.to_s # => "\e[1;31m"
15
15
  class ANSI
16
- # Hash that maps style and color names to their respective ANSI codes.
16
+ # Hash that maps style and color names to their respective ANSI codes.
17
17
  CODES_HASH = {
18
18
  reset_all: 0,
19
19
 
@@ -66,12 +66,24 @@ class ANSI
66
66
  reset_background: 49
67
67
  }.freeze
68
68
 
69
- # @return [Array<Integer>] the ANSI codes stored in the instance.
69
+ # @return [Array<Integer>] the ANSI codes stored in the instance.
70
70
  attr_reader :codes
71
71
 
72
- # Initializes a new instance of the ANSI class.
72
+ # Removes ANSI escape codes from a given string.
73
73
  #
74
- # @param code [Array<Symbol>, Symbol, String] One or more ANSI codes represented as symbols, integers, or strings.
74
+ # This class method is designed to take a string input and remove any ANSI
75
+ # escape codes, which are often used for text formatting in terminal outputs.
76
+ #
77
+ # @param value [String] the string from which ANSI codes should be removed.
78
+ # If the input is not a string, it will be converted to a string using `to_s`.
79
+ # @return [String] a new string with ANSI escape codes removed.
80
+ def self.remove_from_string(value)
81
+ value.to_s.gsub(CONSTANTS::ANSI::TOKEN_REGEX, '')
82
+ end
83
+
84
+ # Initializes a new instance of the ANSI class.
85
+ #
86
+ # @param code [Array<Symbol>, Symbol, String] One or more ANSI codes represented as symbols, integers, or strings.
75
87
  def initialize(code)
76
88
  @codes = if code.is_a?(Array)
77
89
  ANSI.normalize_array_codes(code)
@@ -82,36 +94,36 @@ class ANSI
82
94
  end
83
95
  end
84
96
 
85
- # Adds ANSI codes from another instance of the ANSI class.
97
+ # Adds ANSI codes from another instance of the ANSI class.
86
98
  #
87
- # @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
88
- # @return [ANSI] A new instance of the ANSI class with the combined codes.
89
- # @raise [RuntimeError] If the argument is not an instance of the ANSI class.
99
+ # @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
100
+ # @return [ANSI] A new instance of the ANSI class with the combined codes.
101
+ # @raise [RuntimeError] If the argument is not an instance of the ANSI class.
90
102
  def append(ansi)
91
103
  raise 'Needs be an instance of ANSI' unless ansi.is_a?(ANSI)
92
104
 
93
105
  ANSI.new(@codes.union(ansi.codes))
94
106
  end
95
107
 
96
- # Adds ANSI codes from another instance of the ANSI class and updates the current instance.
108
+ # Adds ANSI codes from another instance of the ANSI class and updates the current instance.
97
109
  #
98
- # @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
99
- # @return [void]
110
+ # @param ansi [ANSI] The instance of the ANSI class whose codes will be added.
111
+ # @return [void]
100
112
  def append!(ansi)
101
113
  @codes = append(ansi).codes
102
114
  end
103
115
 
104
- # Converts the ANSI codes stored in the instance to a formatted string.
116
+ # Converts the ANSI codes stored in the instance to a formatted string.
105
117
  #
106
- # @return [String] The formatted string with the ANSI codes.
118
+ # @return [String] The formatted string with the ANSI codes.
107
119
  def to_s
108
120
  "\e[#{@codes.flatten.join(';')}m"
109
121
  end
110
122
 
111
- # Normalizes an array of codes, converting symbols and strings to their respective ANSI codes.
123
+ # Normalizes an array of codes, converting symbols and strings to their respective ANSI codes.
112
124
  #
113
- # @param array [Array<Symbol, String, Integer>] An array of codes to be normalized.
114
- # @return [Array<Integer>] The normalized array of ANSI codes.
125
+ # @param array [Array<Symbol, String, Integer>] An array of codes to be normalized.
126
+ # @return [Array<Integer>] The normalized array of ANSI codes.
115
127
  def self.normalize_array_codes(array)
116
128
  array.map do |value|
117
129
  next normalize_array_codes(value) if value.is_a?(Array)
@@ -3,25 +3,25 @@
3
3
  require_relative 'constants'
4
4
  require_relative 'ansi'
5
5
 
6
- # The ANSIStyleManager class is responsible for managing and applying ANSI styles to a given string.
6
+ # The ANSIStyleManager class is responsible for managing and applying ANSI styles to a given string.
7
7
  #
8
- # It can replace tokens in the string with corresponding ANSI codes for colors, backgrounds and effects.
8
+ # It can replace tokens in the string with corresponding ANSI codes for colors, backgrounds and effects.
9
9
  #
10
- # ## Effects
10
+ # ## Effects
11
11
  # Effects can be used by adding `<effect:effect_name>` at the beginning and `</effect>` at the end of
12
- # the sequence of characters to which you want the effect to be applied.
13
- #
14
- # Example:
15
- # ```ruby
16
- # manager = ANSIStyleManager.new('The text <effect:bold>Potato</effect> will be bold.')
17
- # puts manager
18
- # ```
19
- # Output:
20
- #
21
- # ![bold output](./.resources/images/bold_effect_example.png)
22
- #
23
- # Below is the table with all available effects:
24
- #
12
+ # the sequence of characters to which you want the effect to be applied.
13
+ #
14
+ # Example:
15
+ # ```ruby
16
+ # manager = ANSIStyleManager.new('The text <effect:bold>Potato</effect> will be bold.')
17
+ # puts manager
18
+ # ```
19
+ # Output:
20
+ #
21
+ # ![bold_effect](./images/bold_effect_example.png)
22
+ #
23
+ # Below is the table with all available effects:
24
+ #
25
25
  # | Effect Name | Description |
26
26
  # |---------------|----------------------------|
27
27
  # | bold | set bold mode. |
@@ -33,45 +33,45 @@ require_relative 'ansi'
33
33
  # | hidden | set hidden/invisible mode. |
34
34
  # | strike | set strikethrough mode. |
35
35
  # | plain | set double underline mode. |
36
- #
37
- # > **Note:** Some terminals may not support some of the effects listed above.
38
- #
39
- # ## Colors
40
- # The ANSIStyleManager supports 3 types of coloring: Named Colors, RGB Colors, or 256 Colors.
41
- #
36
+ #
37
+ # > **Note:** Some terminals may not support some of the effects listed above.
38
+ #
39
+ # ## Colors
40
+ # The ANSIStyleManager supports 3 types of coloring: Named Colors, RGB Colors, or 256 Colors.
41
+ #
42
42
  # The foreground color can be changed by adding `<color:color_type>` at the beginning and `</color>`
43
- # at the end of the character sequence you want to color.
44
- #
45
- # Example:
46
- # ```ruby
47
- # text = 'A <color:green>colorful <color:red>world <color:yellow>is <color:blue>much '
48
- # text += '</color>more </color>beautiful</color>!</color> ;)'
49
- # manager = ANSIStyleManager.new(text)
50
- # puts manager
51
- # ```
52
- # Output:
53
- #
54
- # ![colored output](./.resources/images/foreground_colored_example.png)
55
- #
56
- # It is also possible to set the background color of a text.
57
- #
43
+ # at the end of the character sequence you want to color.
44
+ #
45
+ # Example:
46
+ # ```ruby
47
+ # text = 'A <color:green>colorful <color:red>world <color:yellow>is <color:blue>much '
48
+ # text += '</color>more </color>beautiful</color>!</color> ;)'
49
+ # manager = ANSIStyleManager.new(text)
50
+ # puts manager
51
+ # ```
52
+ # Output:
53
+ #
54
+ # ![colored output](./images/foreground_colored_example.png)
55
+ #
56
+ # It is also possible to set the background color of a text.
57
+ #
58
58
  # The background color can be changed by adding `<color:color_type:color_type>` at the
59
- # beginning and `</color>` at the end of the character sequence you want to color.
60
- #
61
- # Example:
62
- # ```ruby
63
- # text = 'A <color:green:white>colorful <color:196>world <color:yellow:111>is <color:blue:255;255;255>much '
64
- # text += '</color>more </color>beautiful</color>!</color> ;)'
65
- # manager = ANSIStyleManager.new(text)
66
- # puts manager
67
- # ```
68
- #
69
- # Output:
70
- #
71
- # ![colored output](./.resources/images/background_colored_exemple.png)
72
- #
73
- # Below is the table with all available color type patterns:
74
- #
59
+ # beginning and `</color>` at the end of the character sequence you want to color.
60
+ #
61
+ # Example:
62
+ # ```ruby
63
+ # text = 'A <color:green:white>colorful <color:196>world <color:yellow:111>is <color:blue:255;255;255>much '
64
+ # text += '</color>more </color>beautiful</color>!</color> ;)'
65
+ # manager = ANSIStyleManager.new(text)
66
+ # puts manager
67
+ # ```
68
+ #
69
+ # Output:
70
+ #
71
+ # ![colored output](./images/background_colored_exemple.png)
72
+ #
73
+ # Below is the table with all available color type patterns:
74
+ #
75
75
  # |Color Type |Pattern |Description |
76
76
  # |-------------|--------|---------------------------------------------------------------------------------------------|
77
77
  # |Reset colors |reset |Resets to the terminal's default color. |
@@ -80,30 +80,30 @@ require_relative 'ansi'
80
80
  # |Named Colors |name |Accepts the following color names: black, red, green, yellow, blue, magenta, cyan and white. |
81
81
  #
82
82
  class ANSIStyleManager
83
- # @return [String] the string to which ANSI styles will be applied.
83
+ # @return [String] the string to which ANSI styles will be applied.
84
84
  attr_reader :string
85
85
 
86
- # Initializes a new instance of the ANSIStyleManager class.
86
+ # Initializes a new instance of the ANSIStyleManager class.
87
87
  #
88
- # @param string [String] The string to which ANSI styles will be applied.
89
- # @raise [RuntimeError] If the argument is not a string.
88
+ # @param string [String] The string to which ANSI styles will be applied.
89
+ # @raise [RuntimeError] If the argument is not a string.
90
90
  def initialize(string)
91
91
  raise 'Need initialize with a string' unless string.is_a?(String)
92
92
 
93
93
  @string = String.new(string)
94
94
  end
95
95
 
96
- # Replaces all color and effect tokens in the string with corresponding ANSI codes.
97
- #
98
- # @return [void]
96
+ # Replaces all color and effect tokens in the string with corresponding ANSI codes.
97
+ #
98
+ # @return [void]
99
99
  def replace_all_tokens!
100
100
  replace_color_tokens!
101
101
  replace_effect_tokens!
102
102
  end
103
103
 
104
- # Replaces all color tokens in the string with corresponding ANSI codes.
105
- #
106
- # @return [void]
104
+ # Replaces all color tokens in the string with corresponding ANSI codes.
105
+ #
106
+ # @return [void]
107
107
  def replace_color_tokens!
108
108
  scan_while_find(CONSTANTS::ANSI::COLORS) do |value|
109
109
  colors = value.first.split(':')
@@ -118,9 +118,9 @@ class ANSIStyleManager
118
118
  end
119
119
  end
120
120
 
121
- # Replaces all effect tokens in the string with corresponding ANSI codes.
122
- #
123
- # @return [void]
121
+ # Replaces all effect tokens in the string with corresponding ANSI codes.
122
+ #
123
+ # @return [void]
124
124
  def replace_effect_tokens!
125
125
  scan_while_find(CONSTANTS::ANSI::EFFECTS) do |value|
126
126
  replace_tokens_with!(
@@ -133,9 +133,9 @@ class ANSIStyleManager
133
133
  end
134
134
  end
135
135
 
136
- # Converts the string with all tokens replaced by corresponding ANSI codes.
136
+ # Converts the string with all tokens replaced by corresponding ANSI codes.
137
137
  #
138
- # @return [String] The string with ANSI codes applied.
138
+ # @return [String] The string with ANSI codes applied.
139
139
  def to_s
140
140
  replace_all_tokens!
141
141
  @string
@@ -143,11 +143,11 @@ class ANSIStyleManager
143
143
 
144
144
  private
145
145
 
146
- # Generates the ANSI prefix for a given color and background.
146
+ # Generates the ANSI prefix for a given color and background.
147
147
  #
148
- # @param color [String] The color name or code.
149
- # @param background [String, nil] The background color name or code.
150
- # @return [ANSI] The ANSI instance representing the color and background.
148
+ # @param color [String] The color name or code.
149
+ # @param background [String, nil] The background color name or code.
150
+ # @return [ANSI] The ANSI instance representing the color and background.
151
151
  def color_prefix(color:, background:)
152
152
  color_ansi = generate_color_ansi(color, is_background: false)
153
153
  return color_ansi.to_s if background.nil?
@@ -155,11 +155,11 @@ class ANSIStyleManager
155
155
  generate_color_ansi(background, is_background: true).append(color_ansi)
156
156
  end
157
157
 
158
- # Generates the ANSI instance for a given color.
158
+ # Generates the ANSI instance for a given color.
159
159
  #
160
- # @param color [String] The color name or code.
161
- # @param is_background [Boolean] Whether the color is for the background.
162
- # @return [ANSI] The ANSI instance representing the color.
160
+ # @param color [String] The color name or code.
161
+ # @param is_background [Boolean] Whether the color is for the background.
162
+ # @return [ANSI] The ANSI instance representing the color.
163
163
  def generate_color_ansi(color, is_background:)
164
164
  digit_values = color.scan(CONSTANTS::ANSI::COLOR_DIGITS_REGEX).flatten.compact
165
165
 
@@ -175,25 +175,25 @@ class ANSIStyleManager
175
175
  ANSI.new(is_background ? "background_#{color}" : color)
176
176
  end
177
177
 
178
- # Replaces tokens in the string with corresponding ANSI codes.
178
+ # Replaces tokens in the string with corresponding ANSI codes.
179
179
  #
180
- # @param text [String] The text to be styled.
181
- # @param to_replace [String] The token to be replaced.
182
- # @param ansi_token [ANSI] The ANSI instance representing the style.
183
- # @param ansi_reset_token [ANSI] The ANSI instance representing the reset style.
184
- # @param preserve_reset_token [Boolean] Whether to preserve the reset token in the text.
185
- # @return [void]
180
+ # @param text [String] The text to be styled.
181
+ # @param to_replace [String] The token to be replaced.
182
+ # @param ansi_token [ANSI] The ANSI instance representing the style.
183
+ # @param ansi_reset_token [ANSI] The ANSI instance representing the reset style.
184
+ # @param preserve_reset_token [Boolean] Whether to preserve the reset token in the text.
185
+ # @return [void]
186
186
  def replace_tokens_with!(text:, to_replace:, ansi_token:, ansi_reset_token:, preserve_reset_token:)
187
187
  colored_text = text.gsub(ansi_reset_token.to_s, "#{ansi_reset_token}#{ansi_token}") if preserve_reset_token
188
188
  colored_text = text.gsub(ansi_reset_token.to_s, ansi_token.to_s) unless preserve_reset_token
189
189
  @string.gsub!(to_replace, "#{ansi_token}#{colored_text}#{ansi_reset_token}")
190
190
  end
191
191
 
192
- # Scans the string for tokens matching the given regex and processes them with the provided block.
192
+ # Scans the string for tokens matching the given regex and processes them with the provided block.
193
193
  #
194
- # @param scan_regex [Regexp] The regex to scan for tokens.
195
- # @yieldparam value [Array<String>] The matched tokens.
196
- # @return [void]
194
+ # @param scan_regex [Regexp] The regex to scan for tokens.
195
+ # @yieldparam value [Array<String>] The matched tokens.
196
+ # @return [void]
197
197
  def scan_while_find(scan_regex, &block)
198
198
  result = @string.scan(scan_regex)
199
199
  while result.count.positive?
data/lib/utils/array.rb CHANGED
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Extension to Ruby's Array class to enhance functionality.
3
+ # Extension to Ruby's Array class to enhance functionality.
4
4
  class Array
5
- # Lists all elements in the array with their index.
5
+ # Lists all elements in the array with their index.
6
6
  #
7
- # This method outputs each element of the array to the console, prefixed by its index (1-based).
8
- # The index is right-justified based on the length of the array, ensuring a tidy, column-aligned output.
7
+ # This method outputs each element of the array to the console, prefixed by its index (1-based).
8
+ # The index is right-justified based on the length of the array, ensuring a tidy, column-aligned output.
9
9
  #
10
- # Example output for a 3-element array:
11
- # |1| Element 1
12
- # |2| Element 2
13
- # |3| Element 3
10
+ # @example
11
+ # # output for a 3-element array:
12
+ # |1| Element 1
13
+ # |2| Element 2
14
+ # |3| Element 3
14
15
  #
15
16
  # @return [void]
16
17
  def list_all_elements
@@ -6,6 +6,7 @@ module CONSTANTS
6
6
 
7
7
  # @!visibility private
8
8
  module ANSI
9
+ TOKEN_REGEX = /\e\[(\d|;)+m/.freeze
9
10
  COLOR_DIGITS_REGEX = /^(\d+);(\d+);(\d+)|(\d+)$/.freeze
10
11
  COLOR_TOKEN_VALUE = '(?:[\w|\d]+|\d+\;\d+\;\d+)(?::[\w|\d]+|:\d+;\d+;\d+)?'
11
12
  COLORS = %r{<color:(#{COLOR_TOKEN_VALUE})>((?:(?!<color:#{COLOR_TOKEN_VALUE}>|</color>).)*)</color>}m.freeze
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+
5
+ # Class to represent and process a directory structure.
6
+ # It can be initialized with a hash or a YAML file.
7
+ #
8
+ # ## Using HASH
9
+ #
10
+ # The following example shows how to use DirectoryStructure with a hash.
11
+ # ```ruby
12
+ # hash = {
13
+ # 'lib' => {
14
+ # 'version.rb' => nil,
15
+ # 'source' => [
16
+ # 'file_1.rb',
17
+ # 'file_2.rb',
18
+ # 'file_3.rb'
19
+ # ],
20
+ # 'resource' => {
21
+ # 'images' => [
22
+ # 'potato.png',
23
+ # 'fries.jpeg',
24
+ # 'franch_fries.png'
25
+ # ],
26
+ # 'scripts' => {
27
+ # validation: 'teste.rb',
28
+ # sorting: [
29
+ # 'shellsort.rb',
30
+ # 'quicksort.rb'
31
+ # ],
32
+ # 'build.rb' => nil
33
+ # }
34
+ # },
35
+ # generated: 'file.generated.rb'
36
+ # }
37
+ # }
38
+ # directory_structure = DirectoryStructure.new(hash)
39
+ # puts "That is my directory structure:\n#{directory_structure}"
40
+ #
41
+ # # Output:
42
+ # # That is my directory structure:
43
+ # # lib
44
+ # # ╠═ version.rb
45
+ # # ╠═ source
46
+ # # ║ ╠═ file_1.rb
47
+ # # ║ ╠═ file_2.rb
48
+ # # ║ ╚═ file_3.rb
49
+ # # ╠═ resource
50
+ # # ║ ╠═ images
51
+ # # ║ ║ ╠═ potato.png
52
+ # # ║ ║ ╠═ fries.jpeg
53
+ # # ║ ║ ╚═ franch_fries.png
54
+ # # ║ ╚═ scripts
55
+ # # ║ ╠═ validation
56
+ # # ║ ║ ╚═ teste.rb
57
+ # # ║ ╠═ sorting
58
+ # # ║ ║ ╠═ shellsort.rb
59
+ # # ║ ║ ╚═ quicksort.rb
60
+ # # ║ ╚═ build.rb
61
+ # # ╚═ generated
62
+ # # ╚═ file.generated.rb
63
+ # ```
64
+ #
65
+ # ## Using a YAML/YML File
66
+ #
67
+ # First, you need to create a yml file.
68
+ #
69
+ # Example:
70
+ # ```yml
71
+ # lib:
72
+ # version.rb:
73
+ # source:
74
+ # - file_1.rb
75
+ # - file_2.rb
76
+ # - file_3.rb
77
+ # resource:
78
+ # images:
79
+ # - potato.png
80
+ # - fries.jpeg
81
+ # - franch_fries.png
82
+ # scripts:
83
+ # validation: teste.rb
84
+ # sorting:
85
+ # - shellsort.rb
86
+ # - quicksort.rb
87
+ # build.rb:
88
+ # generated: file.generated.rb
89
+ # ```
90
+ #
91
+ # Considering that the file path is passed as a reference.
92
+ #
93
+ # You can initialize the class as in the example below:
94
+ #
95
+ # ```ruby
96
+ # path = 'Replace/By/Your/YAML/FILE/PATH'
97
+ # directory_structure = DirectoryStructure.new(path)
98
+ # puts "That is my directory structure:\n#{directory_structure}"
99
+ #
100
+ # # Output:
101
+ # # That is my directory structure:
102
+ # # lib
103
+ # # ╠═ version.rb
104
+ # # ╠═ source
105
+ # # ║ ╠═ file_1.rb
106
+ # # ║ ╠═ file_2.rb
107
+ # # ║ ╚═ file_3.rb
108
+ # # ╠═ resource
109
+ # # ║ ╠═ images
110
+ # # ║ ║ ╠═ potato.png
111
+ # # ║ ║ ╠═ fries.jpeg
112
+ # # ║ ║ ╚═ franch_fries.png
113
+ # # ║ ╚═ scripts
114
+ # # ║ ╠═ validation
115
+ # # ║ ║ ╚═ teste.rb
116
+ # # ║ ╠═ sorting
117
+ # # ║ ║ ╠═ shellsort.rb
118
+ # # ║ ║ ╚═ quicksort.rb
119
+ # # ║ ╚═ build.rb
120
+ # # ╚═ generated
121
+ # # ╚═ file.generated.rb
122
+ # ```
123
+ class DirectoryStructure
124
+ # Initializes the DirectoryStructure object.
125
+ #
126
+ # @param content [Hash, String] A hash representing the directory structure or a path to a YAML file.
127
+ # @raise [RuntimeError] If the content is not a Hash or a valid YAML file path.
128
+ def initialize(content)
129
+ if content.is_a?(Hash)
130
+ @dir_hash = content
131
+ elsif File.exist?(content)
132
+ @dir_hash = YAML.load_file(content)
133
+ else
134
+ raise 'Need be initialized with a Hash or yaml file path'
135
+ end
136
+ end
137
+
138
+ # Converts the directory structure to a string representation.
139
+ #
140
+ # @return [String] The string representation of the directory structure.
141
+ def to_s
142
+ @output = String.new('')
143
+ process_node(@dir_hash)
144
+ @output
145
+ end
146
+
147
+ private
148
+
149
+ # Generates the indentation string based on the key.
150
+ #
151
+ # @param key [Symbol] The key indicating the type of indentation.
152
+ # @return [String] The indentation string.
153
+ def generate_indent(key)
154
+ { middle: '║ ', last: ' ' }[key] || ''
155
+ end
156
+
157
+ # Concatenates the node to the output string with the given prefix and indentation.
158
+ #
159
+ # @param node [String] The node to be concatenated.
160
+ # @param prefix [Symbol] The prefix indicating the type of node.
161
+ # @param indent [Array<Symbol>] The array of indentation keys.
162
+ # @return [void]
163
+ def concant(node, prefix:, indent:)
164
+ prefix_string = { middle: '╠═ ', last: '╚═ ' }[prefix] || ''
165
+ indent_string = indent.map { |i| generate_indent(i) }.join
166
+ @output << "#{indent_string}#{prefix_string}#{node}\n"
167
+ end
168
+
169
+ # Processes an array of nodes and concatenates them to the output string.
170
+ #
171
+ # @param array [Array] The array of nodes to be processed.
172
+ # @param indent [Array<Symbol>] The array of indentation keys.
173
+ # @return [void]
174
+ def process_array(array, indent:)
175
+ array.each_with_index do |item, index|
176
+ prefix = index == array.size - 1 ? :last : :middle
177
+ concant(item, prefix: prefix, indent: indent)
178
+ end
179
+ end
180
+
181
+ # Processes a hash of nodes and concatenates them to the output string.
182
+ #
183
+ # @param hash [Hash] The hash of nodes to be processed.
184
+ # @param level [Integer] The current level of indentation.
185
+ # @param indent [Array<Symbol>] The array of indentation keys.
186
+ # @return [void]
187
+ def process_hash(hash, level:, indent:)
188
+ hash.each_with_index do |(key, value), index|
189
+ new_indent = indent.dup
190
+ prefix = :empty
191
+
192
+ if level > new_indent.size
193
+ prefix = index == hash.size - 1 ? :last : :middle
194
+ new_indent = indent + [prefix]
195
+ end
196
+
197
+ concant(key, prefix: prefix, indent: indent)
198
+ process_node(value, indent: new_indent, level: level)
199
+ end
200
+ end
201
+
202
+ # Processes a node (hash, array, or other) and concatenates it to the output string.
203
+ #
204
+ # @param node [Object] The node to be processed.
205
+ # @param level [Integer] The current level of indentation.
206
+ # @param indent [Array<Symbol>] The array of indentation keys.
207
+ # @return [void]
208
+ def process_node(node, level: 0, indent: [''])
209
+ if node.is_a?(Hash)
210
+ process_hash(node, indent: indent, level: level + 1)
211
+ elsif node.is_a?(Array)
212
+ process_array(node, indent: indent)
213
+ elsif !node.nil?
214
+ concant(node, prefix: :last, indent: indent)
215
+ end
216
+ end
217
+ end
data/lib/utils/key.rb CHANGED
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # The Key class is designed to encapsulate strings within a specific prefix and suffix,
4
- # allowing for easy identification and manipulation of placeholders within messages.
4
+ # allowing for easy identification and manipulation of placeholders within messages.
5
5
  # This can be particularly useful in templating systems where placeholders need
6
- # to be dynamically replaced with actual content.
6
+ # to be dynamically replaced with actual content.
7
7
  #
8
8
  # @example Creating a new Key and converting it to a string
9
9
  # key = Key.new("username")
@@ -24,32 +24,32 @@ class Key
24
24
  @value = value.to_s
25
25
  end
26
26
 
27
- # Checks equality of two Key objects based on their value.
27
+ # Checks equality of two Key objects based on their value.
28
28
  #
29
- # @param other [Key] the other Key object to compare with.
30
- # @return [Boolean] true if both Keys have the same value, false otherwise.
29
+ # @param other [Key] the other Key object to compare with.
30
+ # @return [Boolean] true if both Keys have the same value, false otherwise.
31
31
  def ==(other)
32
32
  self.class == other.class && @value == other.value
33
33
  end
34
34
 
35
- # Returns the string representation of the Key, including its prefix and suffix.
36
- #
37
- # @return [String] the string representation of the Key.
35
+ # Returns the string representation of the Key, including its prefix and suffix.
36
+ #
37
+ # @return [String] the string representation of the Key.
38
38
  def to_s
39
39
  "#{Key.prefix}#{@value}#{Key.suffix}"
40
40
  end
41
41
 
42
- # Returns the escaped Regexp representation of the Key.to_s return.
43
- #
44
- # @return [Regexp] the escaped regexp representation of the Key.to_s return.
42
+ # Returns the escaped Regexp representation of the Key.to_s return.
43
+ #
44
+ # @return [Regexp] the escaped regexp representation of the Key.to_s return.
45
45
  def to_regexp
46
46
  /#{Regexp.escape(to_s)}/
47
47
  end
48
48
 
49
- # Finds and returns all Key instances within the given string.
49
+ # Finds and returns all Key instances within the given string.
50
50
  #
51
- # @param value [#to_s] the string to search for keys.
52
- # @return [Array<Key>] an array of Key instances found within the given string.
51
+ # @param value [#to_s] the string to search for keys.
52
+ # @return [Array<Key>] an array of Key instances found within the given string.
53
53
  def self.find_keys_in(value)
54
54
  ep = Regexp.escape(prefix)
55
55
  es = Regexp.escape(suffix)
@@ -58,16 +58,16 @@ class Key
58
58
  end
59
59
  end
60
60
 
61
- # Returns the prefix used to identify the start of a Key in a string.
62
- #
63
- # @return [String] the prefix.
61
+ # Returns the prefix used to identify the start of a Key in a string.
62
+ #
63
+ # @return [String] the prefix.
64
64
  def self.prefix
65
65
  '<||'
66
66
  end
67
67
 
68
- # Returns the suffix used to identify the end of a Key in a string.
69
- #
70
- # @return [String] the suffix.
68
+ # Returns the suffix used to identify the end of a Key in a string.
69
+ #
70
+ # @return [String] the suffix.
71
71
  def self.suffix
72
72
  '||>'
73
73
  end
data/lib/utils/message.rb CHANGED
@@ -3,16 +3,14 @@
3
3
  require_relative File.join('..', 'resources', 'path_helper')
4
4
  require_relative 'key'
5
5
 
6
- # The Message class represents a mechanism for dynamically handling and formatting messages.
7
- #
8
- # It supports the substitution of placeholders within a message template with actual data.
9
- #
6
+ # The Message class represents a mechanism for dynamically handling and formatting messages.
7
+ # It supports the substitution of placeholders within a message template with actual data.
10
8
  # The class leverages file-based message templates, allowing for easy localization or
11
- # customization of messages.
9
+ # customization of messages.
12
10
  #
13
11
  # It integrates seamlessly with the Resources module to access these templates from
14
12
  # a customizable path set via the "SCRIPT_CUSTOM_RESOURCES" environment variable or
15
- # from a default library path.
13
+ # from a default library path.
16
14
  #
17
15
  # @example Creating a new Message instance and formatting it
18
16
  # # Assuming "hellow_world" is a file that says "Hello, world!"
@@ -40,10 +38,11 @@ class Message
40
38
  self.class == other.class && @message == other.message
41
39
  end
42
40
 
43
- # Converts the message template into a string, replacing any placeholders with actual data.
41
+ # Converts the message template into a string, replacing any placeholders with actual data.
44
42
  # This method searches for keys within the message and replaces them with corresponding
45
43
  # content from message files located in either the custom path or the library path and appling
46
- # the given replaces.
44
+ # the given replaces.
45
+ # If the file name have the suffix ".aas.txt", the ANSIStyleManager will be applied to the file.
47
46
  #
48
47
  # @return [String] The formatted message with placeholders substituted with actual content.
49
48
  def to_s
@@ -53,7 +52,7 @@ class Message
53
52
 
54
53
  private
55
54
 
56
- # Determines the custom path for message files, if set through the "SCRIPT_CUSTOM_RESOURCES" environment variable.
55
+ # Determines the custom path for message files, if set through the "SCRIPT_CUSTOM_RESOURCES" environment variable.
57
56
  #
58
57
  # @return [String, nil] The custom path for message files, or nil if not set.
59
58
  def custom_path
@@ -63,15 +62,15 @@ class Message
63
62
  File.join(path, 'messages')
64
63
  end
65
64
 
66
- # Provides the default library path for message files. This path is used as a fallback
67
- # when a message file is not found in the custom path.
65
+ # Provides the default library path for message files.
66
+ # This path is used as a fallback when a message file is not found in the custom path.
68
67
  #
69
68
  # @return [String] The path to the default library of message files.
70
69
  def library_path
71
70
  File.join(Resources.library_path, 'messages')
72
71
  end
73
72
 
74
- # Replaces keys found in the original message with their corresponding values.
73
+ # Replaces keys found in the original message with their corresponding values.
75
74
  #
76
75
  # @param message [String] The original message with keys to be replaced.
77
76
  # @return [String] The message with keys replaced by their corresponding values.
@@ -87,7 +86,7 @@ class Message
87
86
  message
88
87
  end
89
88
 
90
- # Replaces all placeholders in the message with their corresponding values from the @to_replace hash.
89
+ # Replaces all placeholders in the message with their corresponding values from the @to_replace hash.
91
90
  #
92
91
  # @param message [String] The message with placeholders to replace.
93
92
  # @return [String] The message with all placeholders replaced with actual content.
@@ -105,8 +104,8 @@ class Message
105
104
  message
106
105
  end
107
106
 
108
- # Attempts to recover and return the content of a message file identified by the file_name parameter.
109
- # It first looks in the custom path (if defined) and then in the library path.
107
+ # Attempts to recover and return the content of a message file identified by the file_name parameter.
108
+ # It first looks in the custom path (if defined) and then in the library path.
110
109
  #
111
110
  # @param file_name [String] The name of the file containing the message content to be recovered.
112
111
  # @return [String] The content of the message file, or the file_name itself if the file cannot be found.
@@ -123,8 +122,8 @@ class Message
123
122
  file_name
124
123
  end
125
124
 
126
- # Reads and returns the content of a message file located at a specific path.
127
- # If the file name have the suffix ".aas.txt", the ANSIStyleManager will be applied to the file.
125
+ # Reads and returns the content of a message file located at a specific path.
126
+ # If the file name have the suffix ".aas.txt", the ANSIStyleManager will be applied to the file.
128
127
  #
129
128
  # @param path [String] The path where the message file is located.
130
129
  # @param file_name [String] The name of the file to be read.
@@ -3,9 +3,9 @@
3
3
  require_relative 'message'
4
4
  require_relative 'array'
5
5
 
6
- # The Question class facilitates the creation and management of interactive questions in the console.
6
+ # The Question class facilitates the creation and management of interactive questions in the console.
7
7
  # It provides methods to validate and return user input as various data types including boolean,
8
- # float, integer, options (from a list), and string.
8
+ # float, integer, options (from a list), and string.
9
9
  class Question
10
10
  # Initializes a new instance of the Question class.
11
11
  #
@@ -93,11 +93,11 @@ class Question
93
93
  end
94
94
  end
95
95
 
96
- # Reads an index input from the user, ensuring it falls within a specified range.
96
+ # Reads an index input from the user, ensuring it falls within a specified range.
97
97
  #
98
98
  # This method prompts the user to enter an index number. It validates the input to ensure
99
99
  # it is an integer within the range of 0 to (count - 1). If the input is invalid, an error
100
- # message is displayed, and the user is prompted again.
100
+ # message is displayed, and the user is prompted again.
101
101
  #
102
102
  # @param count [Integer] The count of items, setting the upper limit of the valid index range.
103
103
  # @param error_message [String, nil] Custom error message for invalid index inputs.
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'question'
4
+ require_relative 'message'
5
+ require_relative 'ansi'
6
+ require_relative 'key'
7
+
8
+ # This class provides additional methods to the standard Ruby String class,
9
+ # allowing for the removal of ANSI codes, and conversion to Key, Question,
10
+ # and Message objects.
11
+ class String
12
+ # Removes ANSI escape codes from the string.
13
+ #
14
+ # @return [String] a new string with ANSI codes removed.
15
+ def remove_ansi
16
+ ANSI.remove_from_string(self)
17
+ end
18
+
19
+ # Converts the string to a Key object.
20
+ #
21
+ # @return [Key] a new Key object initialized with the string.
22
+ def to_key
23
+ Key.new(self)
24
+ end
25
+
26
+ # Converts the string to a Question object.
27
+ #
28
+ # @return [Question] a new Question object initialized with the string.
29
+ def to_question
30
+ Question.new(self)
31
+ end
32
+
33
+ # Converts the string to a Message object.
34
+ #
35
+ # @param replaces [Hash, nil] optional replacements to be applied in the message.
36
+ # @return [Message] a new Message object initialized with the string and optional replacements.
37
+ def to_message(replaces: nil)
38
+ Message.new(self, replaces: replaces)
39
+ end
40
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mp-utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcio F Paludo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-07-02 00:00:00.000000000 Z
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |
14
14
  Helpers to facilitate scripts Writing.
@@ -32,9 +32,11 @@ files:
32
32
  - lib/utils/ansi_style_manager.rb
33
33
  - lib/utils/array.rb
34
34
  - lib/utils/constants.rb
35
+ - lib/utils/directory_structure.rb
35
36
  - lib/utils/key.rb
36
37
  - lib/utils/message.rb
37
38
  - lib/utils/question.rb
39
+ - lib/utils/string.rb
38
40
  - lib/utils/version_manager.rb
39
41
  homepage: https://github.com/MarcioFPaludo/ruby-mp-utils
40
42
  licenses:
@@ -42,6 +44,7 @@ licenses:
42
44
  metadata:
43
45
  homepage_uri: https://github.com/MarcioFPaludo/ruby-mp-utils
44
46
  source_code_uri: https://github.com/MarcioFPaludo/ruby-mp-utils
47
+ documentation_uri: https://marciofpaludo.github.io/ruby-mp-utils
45
48
  rubygems_mfa_required: 'true'
46
49
  post_install_message:
47
50
  rdoc_options: []