Module: HashDelegatorSelf

Included in:
MarkdownExec::HashDelegatorParent
Defined in:
lib/hash_delegator.rb

Instance Method Summary collapse

Instance Method Details

#apply_color_from_hash(string, color_methods, color_key, default_method: 'plain') ⇒ String

Applies an ANSI color method to a string using a specified color key. The method retrieves the color method from the provided hash. If the color key is not present in the hash, it uses a default color method.

Parameters:

  • string (String)

    The string to be colored.

  • color_methods (Hash)

    A hash where keys are color names (String/Symbol) and values are color methods.

  • color_key (String, Symbol)

    The key representing the desired color method in the color_methods hash.

  • default_method (String) (defaults to: 'plain')

    (optional) Default color method to use if color_key is not found in color_methods. Defaults to ‘plain’.

Returns:

  • (String)

    The colored string.



52
53
54
55
# File 'lib/hash_delegator.rb', line 52

def apply_color_from_hash(string, color_methods, color_key, default_method: 'plain')
  color_method = color_methods.fetch(color_key, default_method).to_sym
  string.to_s.send(color_method)
end

#block_find(blocks, key, value, default = nil) ⇒ Object?

Searches for the first element in a collection where the specified key matches a given value. This method is particularly useful for finding a specific hash-like object within an enumerable collection. If no match is found, it returns a specified default value.

Parameters:

  • blocks (Enumerable)

    The collection of hash-like objects to search.

  • key (Object)

    The key to search for in each element of the collection.

  • value (Object)

    The value to match against each element’s corresponding key value.

  • default (Object, nil) (defaults to: nil)

    The default value to return if no match is found (optional).

Returns:

  • (Object, nil)

    The first matching element or the default value if no match is found.



85
86
87
# File 'lib/hash_delegator.rb', line 85

def block_find(blocks, key, value, default = nil)
  blocks.find { |item| item[key] == value } || default
end

#code_merge(*bodies) ⇒ Object



89
90
91
# File 'lib/hash_delegator.rb', line 89

def code_merge(*bodies)
  merge_lists(*bodies)
end

#count_matches_in_lines(lines, regex) ⇒ Object



93
94
95
# File 'lib/hash_delegator.rb', line 93

def count_matches_in_lines(lines, regex)
  lines.count { |line| line.to_s.match(regex) }
end

#create_directory_for_file(file_path) ⇒ Object



97
98
99
# File 'lib/hash_delegator.rb', line 97

def create_directory_for_file(file_path)
  FileUtils.mkdir_p(File.dirname(file_path))
end

#create_file_and_write_string_with_permissions(file_path, content, chmod_value) ⇒ Object

Creates a file at the specified path, writes the given content to it, and sets file permissions if required. Handles any errors encountered during the process.

Parameters:

  • file_path (String)

    The path where the file will be created.

  • content (String)

    The content to write into the file.

  • chmod_value (Integer)

    The file permission value to set; skips if zero.



107
108
109
110
111
112
113
114
# File 'lib/hash_delegator.rb', line 107

def create_file_and_write_string_with_permissions(file_path, content,
                                                  chmod_value)
  create_directory_for_file(file_path)
  File.write(file_path, content)
  set_file_permissions(file_path, chmod_value) unless chmod_value.zero?
rescue StandardError
  error_handler('create_file_and_write_string_with_permissions')
end

#default_block_title_from_body(fcb) ⇒ Object

Updates the title of an FCB object from its body content if the title is nil or empty.



121
122
123
124
125
# File 'lib/hash_delegator.rb', line 121

def default_block_title_from_body(fcb)
  return unless fcb.title.nil? || fcb.title.empty?

  fcb.derive_title_from_body
end

#delete_consecutive_blank_lines!(blocks_menu) ⇒ Object

delete the current line if it is empty and the previous is also empty



128
129
130
131
132
133
# File 'lib/hash_delegator.rb', line 128

def delete_consecutive_blank_lines!(blocks_menu)
  blocks_menu.process_and_conditionally_delete! do |prev_item, current_item, _next_item|
    prev_item&.fetch(:chrome, nil) && !prev_item&.fetch(:oname).present? &&
      current_item&.fetch(:chrome, nil) && !current_item&.fetch(:oname).present?
  end
end

#error_handler(name = '', opts = {}, error: $!) ⇒ Object

HashDelegator.remove_file_without_standard_errors(temp_blocks_file_path) end



144
145
146
147
148
149
# File 'lib/hash_delegator.rb', line 144

def error_handler(name = '', opts = {}, error: $!)
  Exceptions.error_handler(
    "HashDelegator.#{name} -- #{error}",
    opts
  )
end

#format_execution_streams(key, files = {}) ⇒ String

Formats and returns the execution streams (like stdin, stdout, stderr) for a given key. It concatenates the array of strings found under the specified key in the run_state’s files.

Parameters:

  • key (Symbol)

    The key corresponding to the desired execution stream.

Returns:

  • (String)

    A concatenated string of the execution stream’s contents.



167
168
169
# File 'lib/hash_delegator.rb', line 167

def format_execution_streams(key, files = {})
  (files || {}).fetch(key, []).join
end

#indent_all_lines(body, indent = nil) ⇒ String

Indents all lines in a given string with a specified indentation string.

Parameters:

  • body (String)

    A multi-line string to be indented.

  • indent (String) (defaults to: nil)

    The string used for indentation (default is an empty string).

Returns:

  • (String)

    A single string with each line indented as specified.



175
176
177
178
179
# File 'lib/hash_delegator.rb', line 175

def indent_all_lines(body, indent = nil)
  return body unless indent&.non_empty?

  body.lines.map { |line| indent + line.chomp }.join("\n")
end

#initialize_fcb_names(fcb) ⇒ Object



181
182
183
# File 'lib/hash_delegator.rb', line 181

def initialize_fcb_names(fcb)
  fcb.oname = fcb.dname = fcb.title || ''
end

#join_code_lines(lines) ⇒ Object



185
186
187
# File 'lib/hash_delegator.rb', line 185

def join_code_lines(lines)
  ((lines || []) + ['']).join("\n")
end

#merge_lists(*args) ⇒ Object



189
190
191
192
193
# File 'lib/hash_delegator.rb', line 189

def merge_lists(*args)
  # Filters out nil values, flattens the arrays, and ensures an empty list is returned if no valid lists are provided
  merged = args.compact.flatten
  merged.empty? ? [] : merged
end


195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/hash_delegator.rb', line 195

def next_link_state(block_name_from_cli:, was_using_cli:, block_state:, block_name: nil)
  # Set block_name based on block_name_from_cli
  block_name = @cli_block_name if block_name_from_cli

  # Determine the state of breaker based on was_using_cli and the block type
  # true only when block_name is nil, block_name_from_cli is false, was_using_cli is true, and the block_state.block[:shell] equals BlockType::BASH. In all other scenarios, breaker is false.
  breaker = !block_name && !block_name_from_cli && was_using_cli && block_state.block[:shell] == BlockType::BASH

  # Reset block_name_from_cli if the conditions are not met
  block_name_from_cli ||= false

  [block_name, block_name_from_cli, breaker]
end

#parse_yaml_data_from_body(body) ⇒ Object



209
210
211
212
213
# File 'lib/hash_delegator.rb', line 209

def parse_yaml_data_from_body(body)
  body.any? ? YAML.load(body.join("\n")) : {}
rescue StandardError
  error_handler('parse_yaml_data_from_body', { abort: true })
end

#read_required_blocks_from_temp_file(temp_blocks_file_path) ⇒ Array<String>

Reads required code blocks from a temporary file specified by an environment variable.

Returns:

  • (Array<String>)

    Lines read from the temporary file, or an empty array if file is not found or path is empty.



217
218
219
220
221
222
223
224
225
226
227
# File 'lib/hash_delegator.rb', line 217

def read_required_blocks_from_temp_file(temp_blocks_file_path)
  return [] if temp_blocks_file_path.to_s.empty?

  if File.exist?(temp_blocks_file_path)
    File.readlines(
      temp_blocks_file_path, chomp: true
    )
  else
    []
  end
end

#remove_file_without_standard_errors(path) ⇒ Object



229
230
231
# File 'lib/hash_delegator.rb', line 229

def remove_file_without_standard_errors(path)
  FileUtils.rm_f(path)
end

#safeval(str) ⇒ Object

Evaluates the given string as Ruby code and rescues any StandardErrors. If an error occurs, it calls the error_handler method with ‘safeval’.

Parameters:

  • str (String)

    The string to be evaluated.

Returns:

  • (Object)

    The result of evaluating the string.



237
238
239
240
241
# File 'lib/hash_delegator.rb', line 237

def safeval(str)
  eval(str)
rescue StandardError # catches NameError, StandardError
  error_handler('safeval')
end

#set_file_permissions(file_path, chmod_value) ⇒ Object



243
244
245
# File 'lib/hash_delegator.rb', line 243

def set_file_permissions(file_path, chmod_value)
  File.chmod(chmod_value, file_path)
end

#tty_prompt_without_disabled_symbolTTY::Prompt

Creates a TTY prompt with custom settings. Specifically, it disables the default ‘cross’ symbol and defines a lambda function to handle interrupts.

Returns:

  • (TTY::Prompt)

    A new TTY::Prompt instance with specified configurations.



250
251
252
253
254
255
256
257
258
# File 'lib/hash_delegator.rb', line 250

def tty_prompt_without_disabled_symbol
  TTY::Prompt.new(
    interrupt: lambda {
      puts
      raise TTY::Reader::InputInterrupt
    },
    symbols: { cross: ' ' }
  )
end

#update_menu_attrib_yield_selected(fcb:, messages:, configuration: {}, &block) ⇒ Object

Updates the attributes of the given fcb object and conditionally yields to a block. It initializes fcb names and sets the default block title from fcb’s body. If the fcb has a body and meets certain conditions, it yields to the given block.

Parameters:

  • fcb (Object)

    The fcb object whose attributes are to be updated.

  • selected_messages (Array<Symbol>)

    A list of message types to determine if yielding is applicable.

  • block (Block)

    An optional block to yield to if conditions are met.



267
268
269
270
271
272
273
274
# File 'lib/hash_delegator.rb', line 267

def update_menu_attrib_yield_selected(fcb:, messages:, configuration: {}, &block)
  initialize_fcb_names(fcb)
  return unless fcb.body

  default_block_title_from_body(fcb)
  MarkdownExec::Filter.yield_to_block_if_applicable(fcb, messages, configuration,
                                                    &block)
end

#write_execution_output_to_file(files, filespec) ⇒ Object



276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/hash_delegator.rb', line 276

def write_execution_output_to_file(files, filespec)
  FileUtils.mkdir_p File.dirname(filespec)

  File.write(
    filespec,
    ["-STDOUT-\n",
     format_execution_streams(ExecutionStreams::StdOut, files),
     "-STDERR-\n",
     format_execution_streams(ExecutionStreams::StdErr, files),
     "-STDIN-\n",
     format_execution_streams(ExecutionStreams::StdIn, files),
     "\n"].join
  )
end

#yield_line_if_selected(line, selected_messages, &block) ⇒ Object

Yields a line as a new block if the selected message type includes :line.

Parameters:

  • line (String)

    The line to be processed.

  • selected_messages (Array<Symbol>)

    A list of message types to check.

  • block (Proc)

    The block to be called with the line data.



295
296
297
298
299
# File 'lib/hash_delegator.rb', line 295

def yield_line_if_selected(line, selected_messages, &block)
  return unless block && selected_messages.include?(:line)

  block.call(:line, MarkdownExec::FCB.new(body: [line]))
end