markdown_exec 1.8.4 → 1.8.6

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.
@@ -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