markdown_exec 1.8.4 → 1.8.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -26,6 +26,7 @@ require_relative 'fout'
26
26
  require_relative 'hash'
27
27
  require_relative 'link_history'
28
28
  require_relative 'mdoc'
29
+ require_relative 'regexp'
29
30
  require_relative 'string_util'
30
31
 
31
32
  class String
@@ -296,17 +297,18 @@ module MarkdownExec
296
297
  label_format_below: @delegate_object[:shell_code_label_format_below],
297
298
  block_source: block_source
298
299
  )
300
+ dependencies = (link_state&.inherited_dependencies || {}).merge(required[:dependencies] || {})
299
301
  required[:unmet_dependencies] =
300
302
  (required[:unmet_dependencies] || []) - (link_state&.inherited_block_names || [])
301
303
  if required[:unmet_dependencies].present?
302
304
  ### filter against link_state.inherited_block_names
303
305
 
304
- warn format_and_highlight_dependencies(required[:dependencies],
306
+ warn format_and_highlight_dependencies(dependencies,
305
307
  highlight: required[:unmet_dependencies])
306
308
  runtime_exception(:runtime_exception_error_level,
307
309
  'unmet_dependencies, flag: runtime_exception_error_level', required[:unmet_dependencies])
308
310
  elsif true
309
- warn format_and_highlight_dependencies(required[:dependencies],
311
+ warn format_and_highlight_dependencies(dependencies,
310
312
  highlight: [@delegate_object[:block_name]])
311
313
  end
312
314
 
@@ -357,7 +359,7 @@ module MarkdownExec
357
359
  @fout.fout "Error ENOENT: #{err.inspect}"
358
360
  end
359
361
 
360
- def command_or_user_selected_block(all_blocks, menu_blocks, default)
362
+ def load_cli_or_user_selected_block(all_blocks, menu_blocks, default)
361
363
  if @delegate_object[:block_name].present?
362
364
  block = all_blocks.find do |item|
363
365
  item[:oname] == @delegate_object[:block_name]
@@ -371,7 +373,7 @@ module MarkdownExec
371
373
 
372
374
  SelectedBlockMenuState.new(block, state)
373
375
  rescue StandardError
374
- error_handler('command_or_user_selected_block')
376
+ error_handler('load_cli_or_user_selected_block')
375
377
  end
376
378
 
377
379
  # This method is responsible for handling the execution of generic blocks in a markdown document.
@@ -381,13 +383,13 @@ module MarkdownExec
381
383
  # @param mdoc [Object] The markdown document object containing code blocks.
382
384
  # @param selected [Hash] The selected item from the menu to be executed.
383
385
  # @return [LoadFileLinkState] An object indicating whether to load the next block or reuse the current one.
384
- def compile_execute_bash_and_special_blocks_and_trigger_reuse(mdoc, selected,
385
- link_state = nil, block_source:)
386
+ def compile_execute_and_trigger_reuse(mdoc, selected, link_state = nil, block_source:)
386
387
  required_lines = collect_required_code_lines(mdoc, selected, link_state,
387
388
  block_source: block_source)
388
389
  output_or_approval = @delegate_object[:output_script] || @delegate_object[:user_must_approve]
389
390
  display_required_code(required_lines) if output_or_approval
390
391
  allow_execution = @delegate_object[:user_must_approve] ? prompt_for_user_approval(required_lines) : true
392
+
391
393
  execute_required_lines(required_lines) if allow_execution
392
394
 
393
395
  link_state.block_name = nil
@@ -599,8 +601,8 @@ module MarkdownExec
599
601
  # @param opts [Hash] Options hash containing configuration settings.
600
602
  # @param mdoc [YourMDocClass] An instance of the MDoc class.
601
603
  #
602
- def execute_bash_and_special_blocks(selected, mdoc, link_state = LinkState.new,
603
- block_source:)
604
+ def execute_shell_type(selected, mdoc, link_state = LinkState.new,
605
+ block_source:)
604
606
  if selected.fetch(:shell, '') == BlockType::LINK
605
607
  push_link_history_and_trigger_load(selected.fetch(:body, ''), mdoc, selected,
606
608
  link_state)
@@ -609,11 +611,14 @@ module MarkdownExec
609
611
  pop_link_history_and_trigger_load
610
612
 
611
613
  elsif selected[:shell] == BlockType::OPTS
612
- update_options_and_trigger_reuse(selected, @menu_base_options, link_state)
614
+ options_state = read_show_options_and_trigger_reuse(selected, link_state)
615
+ @menu_base_options.merge!(options_state.options)
616
+ @delegate_object.merge!(options_state.options)
617
+ options_state.load_file_link_state
613
618
 
614
619
  else
615
- compile_execute_bash_and_special_blocks_and_trigger_reuse(mdoc, selected, link_state,
616
- block_source: block_source)
620
+ compile_execute_and_trigger_reuse(mdoc, selected, link_state,
621
+ block_source: block_source)
617
622
  end
618
623
  end
619
624
 
@@ -805,7 +810,7 @@ module MarkdownExec
805
810
 
806
811
  def link_history_push_and_next(
807
812
  curr_block_name:, curr_document_filename:,
808
- inherited_block_names:, inherited_lines:,
813
+ inherited_block_names:, inherited_dependencies:, inherited_lines:,
809
814
  next_block_name:, next_document_filename:,
810
815
  next_load_file:
811
816
  )
@@ -814,6 +819,7 @@ module MarkdownExec
814
819
  block_name: curr_block_name,
815
820
  document_filename: curr_document_filename,
816
821
  inherited_block_names: inherited_block_names,
822
+ inherited_dependencies: inherited_dependencies,
817
823
  inherited_lines: inherited_lines
818
824
  )
819
825
  )
@@ -823,6 +829,7 @@ module MarkdownExec
823
829
  block_name: next_block_name,
824
830
  document_filename: next_document_filename,
825
831
  inherited_block_names: inherited_block_names,
832
+ inherited_dependencies: inherited_dependencies,
826
833
  inherited_lines: inherited_lines
827
834
  )
828
835
  )
@@ -841,7 +848,10 @@ module MarkdownExec
841
848
  block = block_find(all_blocks, :oname, block_name)
842
849
  return unless block
843
850
 
844
- update_options_and_trigger_reuse(block, @delegate_object)
851
+ options_state = read_show_options_and_trigger_reuse(block)
852
+ @menu_base_options.merge!(options_state.options)
853
+ @delegate_object.merge!(options_state.options)
854
+
845
855
  @most_recent_loaded_filename = @delegate_object[:filename]
846
856
  true
847
857
  end
@@ -911,10 +921,12 @@ module MarkdownExec
911
921
  end
912
922
  end
913
923
 
914
- def pop_cli_argument!
915
- return false unless @delegate_object[:input_cli_rest].present?
924
+ def shift_cli_argument!
925
+ return false unless @menu_base_options[:input_cli_rest].present?
916
926
 
917
- @cli_block_name = @delegate_object[:input_cli_rest].pop
927
+ @cli_block_name = @menu_base_options[:input_cli_rest].shift
928
+ # @delegate_object[:input_cli_rest].shift
929
+ # p [__LINE__, @cli_block_name, @menu_base_options[:input_cli_rest]]
918
930
  true
919
931
  end
920
932
 
@@ -978,6 +990,25 @@ module MarkdownExec
978
990
  body.any? ? YAML.load(body.join("\n")) : {}
979
991
  end
980
992
 
993
+ def pop_add_current_code_to_head_and_trigger_load(_link_state, block_names, code_lines,
994
+ dependencies)
995
+ pop = @link_history.pop # updatable
996
+ next_link_state = LinkState.new(
997
+ block_name: pop.block_name,
998
+ document_filename: pop.document_filename,
999
+ inherited_block_names:
1000
+ (pop.inherited_block_names + block_names).sort.uniq,
1001
+ inherited_dependencies:
1002
+ dependencies.merge(pop.inherited_dependencies || {}), ### merge, not replace, key data
1003
+ inherited_lines:
1004
+ code_merge(pop.inherited_lines, code_lines)
1005
+ )
1006
+ @link_history.push(next_link_state)
1007
+
1008
+ next_link_state.block_name = nil
1009
+ LoadFileLinkState.new(LoadFile::Load, next_link_state)
1010
+ end
1011
+
981
1012
  # This method handles the back-link operation in the Markdown execution context.
982
1013
  # It updates the history state and prepares to load the next block.
983
1014
  #
@@ -986,10 +1017,11 @@ module MarkdownExec
986
1017
  pop = @link_history.pop
987
1018
  peek = @link_history.peek
988
1019
  LoadFileLinkState.new(LoadFile::Load, LinkState.new(
989
- document_filename: pop.document_filename,
990
- inherited_block_names: peek.inherited_block_names,
991
- inherited_lines: peek.inherited_lines
992
- ))
1020
+ document_filename: pop.document_filename,
1021
+ inherited_block_names: peek.inherited_block_names,
1022
+ inherited_dependencies: peek.inherited_dependencies,
1023
+ inherited_lines: peek.inherited_lines
1024
+ ))
993
1025
  end
994
1026
 
995
1027
  def post_execution_process
@@ -1135,21 +1167,52 @@ module MarkdownExec
1135
1167
  )
1136
1168
  code_lines = code_info[:code]
1137
1169
  block_names = code_info[:block_names]
1170
+ dependencies = code_info[:dependencies]
1138
1171
  else
1139
1172
  block_names = []
1140
1173
  code_lines = []
1174
+ dependencies = {}
1141
1175
  end
1142
-
1143
1176
  next_document_filename = link_block_data['file'] || @delegate_object[:filename]
1144
- link_history_push_and_next(
1145
- curr_block_name: selected[:oname],
1146
- curr_document_filename: @delegate_object[:filename],
1147
- inherited_block_names: ((link_state&.inherited_block_names || []) + block_names).sort.uniq,
1148
- inherited_lines: code_merge(link_state&.inherited_lines, code_lines),
1149
- next_block_name: link_block_data['block'] || '',
1150
- next_document_filename: next_document_filename,
1151
- next_load_file: next_document_filename == @delegate_object[:filename] ? LoadFile::Reuse : LoadFile::Load
1152
- )
1177
+
1178
+ # if an eval link block, evaluate code_lines and return its standard output
1179
+ #
1180
+ if link_block_data.fetch('eval', false)
1181
+ all_code = code_merge(link_state&.inherited_lines, code_lines)
1182
+ output = `#{all_code.join("\n")}`.split("\n")
1183
+ label_format_above = @delegate_object[:shell_code_label_format_above]
1184
+ label_format_below = @delegate_object[:shell_code_label_format_below]
1185
+ block_source = { document_filename: link_state&.document_filename }
1186
+
1187
+ code_lines = [label_format_above && format(label_format_above,
1188
+ block_source.merge({ block_name: selected[:oname] }))] +
1189
+ output.map do |line|
1190
+ re = Regexp.new(link_block_data.fetch('pattern', '(?<line>.*)'))
1191
+ if re =~ line
1192
+ re.gsub_format(line, link_block_data.fetch('format', '%{line}'))
1193
+ end
1194
+ end.compact +
1195
+ [label_format_below && format(label_format_below,
1196
+ block_source.merge({ block_name: selected[:oname] }))]
1197
+
1198
+ end
1199
+
1200
+ if link_block_data['return']
1201
+ pop_add_current_code_to_head_and_trigger_load(link_state, block_names, code_lines,
1202
+ dependencies)
1203
+
1204
+ else
1205
+ link_history_push_and_next(
1206
+ curr_block_name: selected[:oname],
1207
+ curr_document_filename: @delegate_object[:filename],
1208
+ inherited_block_names: ((link_state&.inherited_block_names || []) + block_names).sort.uniq,
1209
+ inherited_dependencies: (link_state&.inherited_dependencies || {}).merge(dependencies || {}), ### merge, not replace, key data
1210
+ inherited_lines: code_merge(link_state&.inherited_lines, code_lines),
1211
+ next_block_name: link_block_data['block'] || '',
1212
+ next_document_filename: next_document_filename,
1213
+ next_load_file: next_document_filename == @delegate_object[:filename] ? LoadFile::Reuse : LoadFile::Load
1214
+ )
1215
+ end
1153
1216
  end
1154
1217
 
1155
1218
  # Reads required code blocks from a temporary file specified by an environment variable.
@@ -1210,86 +1273,208 @@ module MarkdownExec
1210
1273
  # Markdown document, obtain approval, and execute the chosen block of code.
1211
1274
  #
1212
1275
  # @return [Nil] Returns nil if no code block is selected or an error occurs.
1213
- def select_execute_bash_and_special_blocks(_execute: true)
1276
+ def document_menu_loop
1214
1277
  @menu_base_options = @delegate_object
1278
+ link_state, block_name_from_cli, now_using_cli = initialize_selection_states
1279
+ menu_default_dname = nil
1280
+
1281
+ loop do
1282
+ # @bsp 'loop',block_name_from_cli,@cli_block_name
1283
+ block_name_from_cli, now_using_cli, blocks_in_file, menu_blocks, mdoc = \
1284
+ set_delobj_menu_loop_vars(block_name_from_cli, now_using_cli, link_state)
1285
+
1286
+ # cli or user selection
1287
+ #
1288
+ block_state = load_cli_or_user_selected_block(blocks_in_file, menu_blocks,
1289
+ menu_default_dname)
1290
+ if block_state.state == MenuState::EXIT
1291
+ # @bsp 'MenuState::EXIT -> break'
1292
+ break
1293
+ end
1294
+
1295
+ dump_and_warn_block_state(block_state.block)
1296
+ link_state, menu_default_dname = exec_bash_next_state(block_state.block, mdoc,
1297
+ link_state)
1298
+ if prompt_user_exit(block_name_from_cli, block_state.block)
1299
+ # @bsp 'prompt_user_exit -> break'
1300
+ break
1301
+ end
1302
+
1303
+ link_state.block_name, block_name_from_cli, cli_break = \
1304
+ next_state_from_cli(now_using_cli, block_state)
1305
+
1306
+ if cli_break
1307
+ # @bsp 'read_block_name_from_cli + next_link_state -> break'
1308
+ break
1309
+ end
1310
+ end
1311
+ rescue StandardError
1312
+ error_handler('document_menu_loop',
1313
+ { abort: true })
1314
+ end
1315
+
1316
+ def next_state_from_cli(now_using_cli, block_state)
1317
+ was_using_cli = now_using_cli
1318
+ block_name_from_cli, = read_block_name_from_cli(now_using_cli)
1319
+ block_name, block_name_from_cli, cli_break = \
1320
+ next_link_state(block_name_from_cli, was_using_cli, block_state)
1321
+
1322
+ [block_name, block_name_from_cli, cli_break]
1323
+ end
1324
+
1325
+ def exec_bash_next_state(block_state_block, mdoc, link_state)
1326
+ lfls = execute_shell_type(
1327
+ block_state_block,
1328
+ mdoc,
1329
+ link_state,
1330
+ block_source: { document_filename: @delegate_object[:filename] }
1331
+ )
1332
+
1333
+ # if the same menu is being displayed, collect the display name of the selected menu item for use as the default item
1334
+ [lfls.link_state,
1335
+ lfls.load_file == LoadFile::Load ? nil : block_state_block[:dname]]
1336
+ end
1337
+
1338
+ def set_delobj_menu_loop_vars(block_name_from_cli, now_using_cli, link_state)
1339
+ block_name_from_cli, now_using_cli = \
1340
+ manage_cli_selection_state(block_name_from_cli, now_using_cli, link_state)
1341
+ set_delob_filename_block_name(link_state, block_name_from_cli)
1342
+
1343
+ # update @delegate_object and @menu_base_options in auto_load
1344
+ #
1345
+ blocks_in_file, menu_blocks, mdoc = mdoc_menu_and_blocks_from_nested_files
1346
+ dump_delobj(blocks_in_file, menu_blocks, link_state)
1347
+
1348
+ [block_name_from_cli, now_using_cli, blocks_in_file, menu_blocks, mdoc]
1349
+ end
1350
+
1351
+ # user prompt to exit if the menu will be displayed again
1352
+ #
1353
+ def prompt_user_exit(block_name_from_cli, block_state_block)
1354
+ !block_name_from_cli &&
1355
+ block_state_block[:shell] == BlockType::BASH &&
1356
+ @delegate_object[:pause_after_script_execution] &&
1357
+ prompt_select_continue == MenuState::EXIT
1358
+ end
1359
+
1360
+ def manage_cli_selection_state(block_name_from_cli, now_using_cli, link_state)
1361
+ if block_name_from_cli && @cli_block_name == '.'
1362
+ # @bsp 'pause cli control, allow user to select block'
1363
+ block_name_from_cli = false
1364
+ now_using_cli = false
1365
+ @menu_base_options[:block_name] = \
1366
+ @delegate_object[:block_name] = \
1367
+ link_state.block_name = \
1368
+ @cli_block_name = nil
1369
+ end
1370
+
1371
+ @delegate_object = @menu_base_options.dup
1372
+ @menu_user_clicked_back_link = false
1373
+ [block_name_from_cli, now_using_cli]
1374
+ end
1375
+
1376
+ def next_link_state(block_name_from_cli, was_using_cli, block_state)
1377
+ # @bsp 'next_link_state',block_name_from_cli, was_using_cli, block_state
1378
+ # Set block_name based on block_name_from_cli
1379
+ block_name = block_name_from_cli ? @cli_block_name : nil
1380
+
1381
+ # Determine the state of breaker based on was_using_cli and the block type
1382
+ breaker = !block_name_from_cli && was_using_cli && block_state.block[:shell] == BlockType::BASH
1383
+
1384
+ # Reset block_name_from_cli if the conditions are not met
1385
+ block_name_from_cli ||= false
1386
+
1387
+ [block_name, block_name_from_cli, breaker]
1388
+ end
1389
+
1390
+ # Initialize the selection states for the execution loop.
1391
+ def initialize_selection_states
1215
1392
  link_state = LinkState.new(
1216
1393
  block_name: @delegate_object[:block_name],
1217
1394
  document_filename: @delegate_object[:filename]
1218
1395
  )
1396
+ block_name_from_cli, now_using_cli = handle_cli_block_name(link_state)
1397
+ [link_state, block_name_from_cli, now_using_cli]
1398
+ end
1399
+
1400
+ # Update the state related to CLI block name.
1401
+ #
1402
+ # This method updates the flags indicating whether a CLI block name is being used
1403
+ # and if it was being used previously.
1404
+ #
1405
+ # @param block_name_from_cli [Boolean] Indicates if the block name is from CLI.
1406
+ # @return [Array] Returns the updated state of block name from CLI and its usage.
1407
+ def read_block_name_from_cli(block_name_from_cli)
1408
+ # was_using_cli = block_name_from_cli
1409
+ block_name_from_cli = shift_cli_argument!
1410
+ now_using_cli = block_name_from_cli
1411
+
1412
+ [block_name_from_cli, now_using_cli]
1413
+ end
1414
+
1415
+ # Update the block name in the link state and delegate object.
1416
+ #
1417
+ # This method updates the block name based on whether it was specified
1418
+ # through the CLI or derived from the link state.
1419
+ #
1420
+ # @param link_state [LinkState] The current link state object.
1421
+ # @param block_name_from_cli [Boolean] Indicates if the block name is from CLI.
1422
+ def set_delob_filename_block_name(link_state, block_name_from_cli)
1423
+ @delegate_object[:filename] = link_state.document_filename
1424
+ link_state.block_name = @delegate_object[:block_name] =
1425
+ block_name_from_cli ? @cli_block_name : link_state.block_name
1426
+ end
1427
+
1428
+ # Handle CLI block name and determine the current CLI usage state.
1429
+ #
1430
+ # This method processes the CLI block name from the link state and sets
1431
+ # the initial state for CLI usage.
1432
+ #
1433
+ # @param link_state [LinkState] The current link state object.
1434
+ # @return [Array] Returns the state of block name from CLI and current usage of CLI.
1435
+ def handle_cli_block_name(link_state)
1219
1436
  block_name_from_cli = link_state.block_name.present?
1220
1437
  @cli_block_name = link_state.block_name
1221
- load_file = nil
1222
- menu_default_dname = nil
1438
+ now_using_cli = block_name_from_cli
1223
1439
 
1224
- loop do
1225
- loop do
1226
- @delegate_object = @menu_base_options.dup
1227
- @menu_user_clicked_back_link = false
1228
- @delegate_object[:filename] = link_state.document_filename
1229
- link_state.block_name = @delegate_object[:block_name] =
1230
- block_name_from_cli ? @cli_block_name : link_state.block_name
1231
-
1232
- blocks_in_file, menu_blocks, mdoc = mdoc_menu_and_blocks_from_nested_files
1233
-
1234
- if @delegate_object[:dump_blocks_in_file]
1235
- warn format_and_highlight_dependencies(
1236
- compact_and_index_hash(blocks_in_file),
1237
- label: 'blocks_in_file'
1238
- )
1239
- end
1240
- if @delegate_object[:dump_menu_blocks]
1241
- warn format_and_highlight_dependencies(
1242
- compact_and_index_hash(menu_blocks),
1243
- label: 'menu_blocks'
1244
- )
1245
- end
1246
-
1247
- block_state = command_or_user_selected_block(blocks_in_file,
1248
- menu_blocks, menu_default_dname)
1249
- return if block_state.state == MenuState::EXIT
1440
+ [block_name_from_cli, now_using_cli]
1441
+ end
1250
1442
 
1251
- if block_state.block.nil?
1252
- warn_format('select_execute_bash_and_special_blocks', "Block not found -- #{@delegate_object[:block_name]}",
1253
- { abort: true })
1254
- # error_handler("Block not found -- #{opts[:block_name]}", { abort: true })
1255
- end
1443
+ # Outputs warnings based on the delegate object's configuration
1444
+ #
1445
+ # @param delegate_object [Hash] The delegate object containing configuration flags.
1446
+ # @param blocks_in_file [Hash] Hash of blocks present in the file.
1447
+ # @param menu_blocks [Hash] Hash of menu blocks.
1448
+ # @param link_state [LinkState] Current state of the link.
1449
+ def dump_delobj(blocks_in_file, menu_blocks, link_state)
1450
+ if @delegate_object[:dump_delegate_object]
1451
+ warn format_and_highlight_hash(@delegate_object, label: '@delegate_object')
1452
+ end
1256
1453
 
1257
- if @delegate_object[:dump_selected_block]
1258
- warn block_state.block.to_yaml.sub(/^(?:---\n)?/, "Block:\n")
1259
- end
1454
+ if @delegate_object[:dump_blocks_in_file]
1455
+ warn format_and_highlight_dependencies(compact_and_index_hash(blocks_in_file),
1456
+ label: 'blocks_in_file')
1457
+ end
1260
1458
 
1261
- load_file_link_state = execute_bash_and_special_blocks(
1262
- block_state.block,
1263
- mdoc,
1264
- link_state,
1265
- block_source: { document_filename: @delegate_object[:filename] }
1266
- )
1267
- load_file = load_file_link_state.load_file
1268
- link_state = load_file_link_state.link_state
1269
- # if the same menu is being displayed, collect the display name of the selected menu item for use as the default item
1270
- menu_default_dname = load_file == LoadFile::Load ? nil : block_state.block[:dname]
1459
+ if @delegate_object[:dump_menu_blocks]
1460
+ warn format_and_highlight_dependencies(compact_and_index_hash(menu_blocks),
1461
+ label: 'menu_blocks')
1462
+ end
1271
1463
 
1272
- # user prompt to exit if the menu will be displayed again
1273
- #
1274
- if !block_name_from_cli &&
1275
- block_state.block[:shell] == BlockType::BASH &&
1276
- @delegate_object[:pause_after_script_execution] &&
1277
- prompt_select_continue == MenuState::EXIT
1278
- return
1279
- end
1464
+ return unless @delegate_object[:dump_inherited_lines]
1280
1465
 
1281
- # exit current document/menu if loading next document or single block_name was specified
1282
- #
1283
- break if block_state.state == MenuState::CONTINUE && load_file == LoadFile::Load
1284
- break if block_name_from_cli
1285
- end
1286
- break if load_file == LoadFile::Reuse
1466
+ warn format_and_highlight_lines(link_state.inherited_lines, label: 'inherited_lines')
1467
+ end
1287
1468
 
1288
- block_name_from_cli = pop_cli_argument!
1469
+ def dump_and_warn_block_state(block_state_block)
1470
+ if block_state_block.nil?
1471
+ Exceptions.warn_format("Block not found -- name: #{@delegate_object[:block_name]}",
1472
+ { abort: true })
1289
1473
  end
1290
- rescue StandardError
1291
- error_handler('select_execute_bash_and_special_blocks',
1292
- { abort: true })
1474
+
1475
+ return unless @delegate_object[:dump_selected_block]
1476
+
1477
+ warn block_state_block.to_yaml.sub(/^(?:---\n)?/, "Block:\n")
1293
1478
  end
1294
1479
 
1295
1480
  # Presents a TTY prompt to select an option or exit, returns metadata including option and selected
@@ -1406,12 +1591,6 @@ module MarkdownExec
1406
1591
  )
1407
1592
  end
1408
1593
 
1409
- def update_delegate_and_target(key, value, tgt2)
1410
- sym_key = key.to_sym
1411
- @delegate_object[sym_key] = value
1412
- tgt2[sym_key] = value if tgt2
1413
- end
1414
-
1415
1594
  # Updates the hierarchy of document headings based on the given line.
1416
1595
  # Utilizes regular expressions to identify heading levels.
1417
1596
  # @param line [String] The line of text to check for headings.
@@ -1487,6 +1666,10 @@ module MarkdownExec
1487
1666
  # add line if it is depth 0 or option allows it
1488
1667
  #
1489
1668
  yield_line_if_selected(line, selected_messages, &block)
1669
+
1670
+ else
1671
+ # @bsp 'line is not recognized for block state'
1672
+
1490
1673
  end
1491
1674
  end
1492
1675
 
@@ -1509,14 +1692,21 @@ module MarkdownExec
1509
1692
  # @param selected [Hash] Selected item from the menu containing a YAML body.
1510
1693
  # @param tgt2 [Hash, nil] An optional target hash to update with YAML data.
1511
1694
  # @return [LoadFileLinkState] An instance indicating the next action for loading files.
1512
- def update_options_and_trigger_reuse(selected, tgt2 = nil, link_state = LinkState.new)
1695
+ def read_show_options_and_trigger_reuse(selected, link_state = LinkState.new)
1696
+ obj = {}
1513
1697
  data = YAML.load(selected[:body].join("\n"))
1514
1698
  (data || []).each do |key, value|
1515
- update_delegate_and_target(key, value, tgt2)
1699
+ sym_key = key.to_sym
1700
+ obj[sym_key] = value
1701
+
1516
1702
  print_formatted_option(key, value) if @delegate_object[:menu_opts_set_format].present?
1517
1703
  end
1704
+
1518
1705
  link_state.block_name = nil
1519
- LoadFileLinkState.new(LoadFile::Reuse, link_state)
1706
+ OpenStruct.new(options: obj,
1707
+ load_file_link_state: LoadFileLinkState.new(
1708
+ LoadFile::Reuse, link_state
1709
+ ))
1520
1710
  end
1521
1711
 
1522
1712
  def wait_for_stream_processing
@@ -1716,6 +1906,7 @@ if $PROGRAM_NAME == __FILE__
1716
1906
  expected_result = LoadFileLinkState.new(LoadFile::Load,
1717
1907
  LinkState.new(block_name: 'sample_block',
1718
1908
  document_filename: 'sample_file',
1909
+ inherited_dependencies: {},
1719
1910
  inherited_lines: []))
1720
1911
  assert_equal expected_result,
1721
1912
  @hd.push_link_history_and_trigger_load(body, nil, FCB.new(block_name: 'sample_block',
@@ -1904,7 +2095,7 @@ if $PROGRAM_NAME == __FILE__
1904
2095
  @hd.instance_variable_set(:@delegate_object,
1905
2096
  { block_name: 'block1' })
1906
2097
 
1907
- result = @hd.command_or_user_selected_block(all_blocks, [], nil)
2098
+ result = @hd.load_cli_or_user_selected_block(all_blocks, [], nil)
1908
2099
 
1909
2100
  assert_equal all_blocks.first, result.block
1910
2101
  assert_nil result.state
@@ -1915,7 +2106,7 @@ if $PROGRAM_NAME == __FILE__
1915
2106
  :some_state)
1916
2107
  @hd.stubs(:wait_for_user_selected_block).returns(block_state)
1917
2108
 
1918
- result = @hd.command_or_user_selected_block([], [], nil)
2109
+ result = @hd.load_cli_or_user_selected_block([], [], nil)
1919
2110
 
1920
2111
  assert_equal block_state.block, result.block
1921
2112
  assert_equal :some_state, result.state
@@ -2207,7 +2398,7 @@ if $PROGRAM_NAME == __FILE__
2207
2398
  @selected_item = mock('FCB')
2208
2399
  end
2209
2400
 
2210
- def test_compile_execute_bash_and_special_blocks_and_trigger_reuse_without_user_approval
2401
+ def test_compile_execute_and_trigger_reuse_without_user_approval
2211
2402
  # Mock the delegate object configuration
2212
2403
  @hd.instance_variable_set(:@delegate_object,
2213
2404
  { output_script: false,
@@ -2217,7 +2408,7 @@ if $PROGRAM_NAME == __FILE__
2217
2408
  # Expectations and assertions go here
2218
2409
  end
2219
2410
 
2220
- def test_compile_execute_bash_and_special_blocks_and_trigger_reuse_with_user_approval
2411
+ def test_compile_execute_and_trigger_reuse_with_user_approval
2221
2412
  # Mock the delegate object configuration
2222
2413
  @hd.instance_variable_set(:@delegate_object,
2223
2414
  { output_script: false,
@@ -2227,7 +2418,7 @@ if $PROGRAM_NAME == __FILE__
2227
2418
  # Expectations and assertions go here
2228
2419
  end
2229
2420
 
2230
- def test_compile_execute_bash_and_special_blocks_and_trigger_reuse_with_output_script
2421
+ def test_compile_execute_and_trigger_reuse_with_output_script
2231
2422
  # Mock the delegate object configuration
2232
2423
  @hd.instance_variable_set(:@delegate_object,
2233
2424
  { output_script: true,
@@ -2238,40 +2429,6 @@ if $PROGRAM_NAME == __FILE__
2238
2429
  end
2239
2430
  end
2240
2431
 
2241
- class TestHashDelegatorHandleOptsBlock < Minitest::Test
2242
- def setup
2243
- @hd = HashDelegator.new
2244
- @hd.instance_variable_set(:@delegate_object,
2245
- { menu_opts_set_format: 'Option: %<key>s, Value: %<value>s',
2246
- menu_opts_set_color: :blue })
2247
- @hd.stubs(:string_send_color)
2248
- @hd.stubs(:print)
2249
- end
2250
-
2251
- def test_update_options_and_trigger_reuse
2252
- selected = { body: ['option1: value1'] }
2253
- tgt2 = {}
2254
-
2255
- result = @hd.update_options_and_trigger_reuse(selected, tgt2)
2256
-
2257
- assert_instance_of LoadFileLinkState, result
2258
- assert_equal 'value1',
2259
- @hd.instance_variable_get(:@delegate_object)[:option1]
2260
- assert_equal 'value1', tgt2[:option1]
2261
- end
2262
-
2263
- def test_update_options_and_trigger_reuse_without_format
2264
- selected = { body: ['option2: value2'] }
2265
- @hd.instance_variable_set(:@delegate_object, {})
2266
-
2267
- result = @hd.update_options_and_trigger_reuse(selected)
2268
-
2269
- assert_instance_of LoadFileLinkState, result
2270
- assert_equal 'value2',
2271
- @hd.instance_variable_get(:@delegate_object)[:option2]
2272
- end
2273
- end
2274
-
2275
2432
  # require 'stringio'
2276
2433
 
2277
2434
  class TestHashDelegatorHandleStream < Minitest::Test
@@ -2339,39 +2496,6 @@ if $PROGRAM_NAME == __FILE__
2339
2496
  end
2340
2497
  end
2341
2498
 
2342
- class TestHashDelegatorLoadAutoBlocks < Minitest::Test
2343
- def setup
2344
- @hd = HashDelegator.new
2345
- @hd.stubs(:block_find).returns({})
2346
- @hd.stubs(:update_options_and_trigger_reuse)
2347
- end
2348
-
2349
- def test_load_auto_blocks_with_new_filename
2350
- @hd.instance_variable_set(:@delegate_object, {
2351
- document_load_opts_block_name: 'load_block',
2352
- filename: 'new_file'
2353
- })
2354
- assert @hd.load_auto_blocks([])
2355
- end
2356
-
2357
- def test_load_auto_blocks_with_same_filename
2358
- @hd.instance_variable_set(:@delegate_object, {
2359
- document_load_opts_block_name: 'load_block',
2360
- filename: 'new_file'
2361
- })
2362
- @hd.instance_variable_set(:@most_recent_loaded_filename, 'new_file')
2363
- assert_nil @hd.load_auto_blocks([])
2364
- end
2365
-
2366
- def test_load_auto_blocks_without_block_name
2367
- @hd.instance_variable_set(:@delegate_object, {
2368
- document_load_opts_block_name: nil,
2369
- filename: 'new_file'
2370
- })
2371
- assert_nil @hd.load_auto_blocks([])
2372
- end
2373
- end
2374
-
2375
2499
  class TestHashDelegatorMenuChromeColoredOption < Minitest::Test
2376
2500
  def setup
2377
2501
  @hd = HashDelegator.new
@@ -2566,7 +2690,6 @@ if $PROGRAM_NAME == __FILE__
2566
2690
  end
2567
2691
  end
2568
2692
 
2569
- ####
2570
2693
  class TestHashDelegatorYieldToBlock < Minitest::Test
2571
2694
  def setup
2572
2695
  @hd = HashDelegator.new