markdown_exec 3.1.1 → 3.2.0

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: 7b38cc422f735f0c00b0c31e6bd6253bda083e28890475220198109953ce9a74
4
- data.tar.gz: c62e5bc1a2f294b783e4ce53341ae459f46251c25b076e6bb214e483f0c4a2c8
3
+ metadata.gz: 8c39aff829d6b7a3d4eb05134922cdb6fed1d54192fab72ba244d7d7ff73183e
4
+ data.tar.gz: f2bbfa6b9be857c718ba23c1bbc071b91ffe7ba027626c9a27b1d06c8bfce5a9
5
5
  SHA512:
6
- metadata.gz: c1f902747ed7f5688ff734d0b43b8cda0cd9dcff8957290938a8689437c0090660c0534e98c739a7c85a55c066e8604d4593e063382bb68ca46be7e7aae5fc83
7
- data.tar.gz: 1f6fdc9a5640a40159a49547784c09609b1889a4fcd0db7d4e333ff33c2a6a4f3d05ead80b05e4a9b75ae8ce4e880808dae3c37384f0145123824a27bc901ce7
6
+ metadata.gz: 1b97c91ff7b91da388ff9d3aed19ee5e15fd25bd4d6e8f3591a8997614736e27e1c12fb3682a3395bae5853131578b924cbf55284ffda2beb9b89843c8b7c2b7
7
+ data.tar.gz: 3056e41d512fa097204cae511a057b193c5ad3c70e406dee3da1df369bb0bed4f517137cf55e86ac6fcdc1308b70d604c75e9c2c2ee8c9b30edf0d5f574c006e
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [3.2.0] - 2025-07-24
4
+
5
+ ### Added
6
+
7
+ - Option for number of inactive lines requiring a scroll point.
8
+ - Option for variables to not export from a series.
9
+ Some intermediate results are not to be exported.
10
+ Names matching the regular expression are available for
11
+ calculation within the block but not after.
12
+
13
+ ### Changed
14
+
15
+ - Intermediate results are available.
16
+ Fix the evaluation of sequences of expressions by providing
17
+ script lines for intermediate results.
18
+ - Complete backtrace is available for exceptions.
19
+ - Prevent abort when executing a block.
20
+ Often raised by YAML parsing.
21
+
3
22
  ## [3.1.1] - 2025-06-28
4
23
 
5
24
  ### Changed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (3.1.1)
4
+ markdown_exec (3.2.0)
5
5
  clipboard (~> 1.3.6)
6
6
  open3 (~> 0.1.1)
7
7
  optparse (~> 0.1.1)
@@ -61,19 +61,20 @@ transform: '%{major}.%{minor}.%{patch}'
61
61
  name: BRANCH_NAME
62
62
  init: ":exec"
63
63
  exec: "git branch --format='%(refname:short)'"
64
- validate: "^(?<type>feature|bugfix|hotfix)/(?<ticket>[A-Z]+-\d+)-(?<desc>.+)$"
64
+ validate: '^(?<type>feature|bugfix|hotfix)/(?<ticket>[A-Z]+-\d+)-(?<desc>.+)$'
65
65
  transform: "${type}/${ticket}-${desc}"
66
66
  prompt: "Select or enter branch name"
67
67
  ```
68
68
 
69
69
  ### Environment Configuration with Dependencies
70
- ```ux
70
+ ```ux @attrs[:body]
71
71
  name: DATABASE_URL
72
72
  require:
73
73
  - ENVIRONMENT
74
74
  - DB_HOST
75
75
  - DB_PORT
76
- format: "postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
76
+ format: "postgresql://${DB_USER}:${DB_PASS}@${DATABASE_URL}:${DB_PORT}/${DB_NAME}"
77
+ #format: "postgresql://${DB_USER}:${DB_PASS}@${DB_HOST}:${DB_PORT}/${DB_NAME}"
77
78
  ```
78
79
 
79
80
  ### Multi-step Configuration
@@ -104,7 +105,7 @@ require:
104
105
  ```ux
105
106
  name: PHONE_NUMBER
106
107
  prompt: "Enter phone number"
107
- validate: "(?<country>\d{1,3})(?<area>\d{3})(?<number>\d{7})"
108
+ validate: '(?<country>\d{1,3})(?<area>\d{3})(?<number>\d{7})'
108
109
  transform: "+${country} (${area}) ${number}"
109
110
  format: "Phone: ${PHONE_NUMBER}"
110
111
  ```
@@ -114,7 +115,7 @@ format: "Phone: ${PHONE_NUMBER}"
114
115
  name: GIT_STATUS
115
116
  init: ":exec"
116
117
  exec: "git status --porcelain"
117
- validate: "(?<status>[AMDR])\s+(?<file>.+)"
118
+ validate: '(?<status>[AMDR])\s+(?<file>.+)'
118
119
  transform: "${status}: ${file}"
119
120
  format: "Changes: ${GIT_STATUS}"
120
121
  ```
data/lib/fcb.rb CHANGED
@@ -75,6 +75,14 @@ module MarkdownExec
75
75
  full&.to_s&.pub_name(**kwargs)
76
76
  end
77
77
 
78
+ def body
79
+ @attrs[:body]
80
+ end
81
+
82
+ def body=(value)
83
+ @attrs[:body] = value
84
+ end
85
+
78
86
  def code_name_included?(*names)
79
87
  names.include?(@attrs[:oname])
80
88
  end
@@ -93,7 +101,9 @@ module MarkdownExec
93
101
  # 2024-08-04 match nickname
94
102
  # may not exist if block name is duplicated
95
103
  def delete_matching_name!(dependencies)
96
- dependencies.delete(@attrs[:dname]) ||
104
+ ####
105
+ dependencies.delete(@attrs[:id]) ||
106
+ dependencies.delete(@attrs[:dname]) ||
97
107
  dependencies.delete(@attrs[:nickname]) ||
98
108
  dependencies.delete(@attrs[:oname]) ||
99
109
  dependencies.delete(@attrs.pub_name) ||
@@ -271,7 +281,8 @@ module MarkdownExec
271
281
  end
272
282
 
273
283
  def is_named?(name)
274
- @attrs[:dname] == name ||
284
+ @attrs[:id] == name ||
285
+ @attrs[:dname] == name ||
275
286
  @attrs[:nickname] == name ||
276
287
  @attrs[:oname] == name ||
277
288
  @attrs.pub_name == name ||
@@ -361,6 +372,7 @@ module MarkdownExec
361
372
  end
362
373
 
363
374
  # Expand variables in attributes
375
+ # @return [void]
364
376
  def expand_variables_in_attributes!(pattern, replacements)
365
377
  @attrs[:raw_dname] ||= @attrs[:dname]
366
378
  @attrs[:dname] = @attrs[:dname]&.gsub(pattern) do |match|
@@ -1442,12 +1442,17 @@ module MarkdownExec
1442
1442
  # Skip processing for shell-type blocks
1443
1443
  next if exclude_types.include?(block.type)
1444
1444
 
1445
- # Scan each block name for matches of the pattern
1446
- count_named_group_occurrences_block_body_fix_indent(block).scan(pattern) do |(_, _variable_name)|
1447
- pattern.match($LAST_MATCH_INFO.to_s) # Reapply match for named groups
1448
- id = $LAST_MATCH_INFO[group_name]
1449
- occurrence_count[id] += 1
1450
- occurrence_expressions[id] = $LAST_MATCH_INFO['expression']
1445
+ begin
1446
+
1447
+ # Scan each block name for matches of the pattern
1448
+ count_named_group_occurrences_block_body_fix_indent(block).scan(pattern) do |(_, _variable_name)|
1449
+ pattern.match($LAST_MATCH_INFO.to_s) # Reapply match for named groups
1450
+ id = $LAST_MATCH_INFO[group_name]
1451
+ occurrence_count[id] += 1
1452
+ occurrence_expressions[id] = $LAST_MATCH_INFO['expression']
1453
+ end
1454
+ rescue Interrupt
1455
+ binding.irb
1451
1456
  end
1452
1457
  end
1453
1458
 
@@ -2588,6 +2593,8 @@ module MarkdownExec
2588
2593
  pattern: options_command_substitution_regexp
2589
2594
  )
2590
2595
  # no return
2596
+ rescue StandardError
2597
+ wwe 'fcb:', fcb, 'link_state:', link_state
2591
2598
  end
2592
2599
 
2593
2600
  def expand_variable_references!(
@@ -2645,17 +2652,23 @@ module MarkdownExec
2645
2652
  exportable = false
2646
2653
  command_result.warning = warning_required_empty(export) unless silent
2647
2654
  else
2655
+ ### TBD validate/transform?
2656
+ # store the transformed value in ENV
2648
2657
  EnvInterface.set(export.name, command_result.stdout.to_s)
2658
+
2649
2659
  new_lines << { name: export.name, force: force,
2650
2660
  text: command_result.stdout }
2651
2661
  end
2652
2662
 
2653
2663
  when Hash
2664
+ required_lines = []
2665
+
2654
2666
  # each item in the hash is a variable name and value
2655
2667
  export_string.each do |name, expression|
2656
2668
  command_result, = output_from_adhoc_bash_script_file(
2657
2669
  join_array_of_arrays(
2658
2670
  bash_script_lines,
2671
+ required_lines,
2659
2672
  %(printf '%s' "#{expression}")
2660
2673
  ),
2661
2674
  export,
@@ -2664,9 +2677,22 @@ module MarkdownExec
2664
2677
  if command_result.exit_status == EXIT_STATUS_REQUIRED_EMPTY
2665
2678
  command_result.warning = warning_required_empty(export) unless silent
2666
2679
  else
2667
- EnvInterface.set(name, command_result.stdout.to_s)
2668
- new_lines << { name: name, force: force,
2669
- text: command_result.stdout }
2680
+ transformed = command_result.stdout.to_s
2681
+ ### TBD validate/transform?
2682
+ # transformed = if command_result_w_e_t_nl.transformable transform_export_value(name_force[:text], export) else name_force[:text] end
2683
+
2684
+ # code for subsequent expression evaluations
2685
+ required_lines << code_line_to_assign_a_variable(
2686
+ name, transformed, force: force
2687
+ )
2688
+
2689
+ if variable_is_exportable(name)
2690
+ # store the transformed value in ENV
2691
+ EnvInterface.set(name, transformed)
2692
+
2693
+ new_lines << { name: name, force: force,
2694
+ text: command_result.stdout }
2695
+ end
2670
2696
  end
2671
2697
  end
2672
2698
  end
@@ -3266,7 +3292,7 @@ module MarkdownExec
3266
3292
 
3267
3293
  if mdoc
3268
3294
  mdoc.collect_recursively_required_code(
3269
- anyname: fcb.pub_name,
3295
+ anyname: fcb.id,####
3270
3296
  label_format_above: @delegate_object[:shell_code_label_format_above],
3271
3297
  label_format_below: @delegate_object[:shell_code_label_format_below],
3272
3298
  block_source: block_source
@@ -3448,6 +3474,7 @@ module MarkdownExec
3448
3474
  [all_blocks, menu_blocks, mdoc]
3449
3475
  end
3450
3476
 
3477
+ # enable scroll targets in long sequences of inactive lines
3451
3478
  def handle_consecutive_inactive_items!(menu_blocks)
3452
3479
  consecutive_inactive_count = 0
3453
3480
  menu_blocks.each do |fcb|
@@ -3455,7 +3482,10 @@ module MarkdownExec
3455
3482
  consecutive_inactive_count = 0
3456
3483
  else
3457
3484
  consecutive_inactive_count += 1
3458
- if (consecutive_inactive_count % (@delegate_object[:select_page_height] / 3)).zero?
3485
+ if (consecutive_inactive_count %
3486
+ (@delegate_object[:select_page_height] /
3487
+ @delegate_object[:select_page_ratio])
3488
+ ).zero?
3459
3489
  fcb.disabled = TtyMenu::ENABLE
3460
3490
  fcb.is_enabled_but_inactive = true
3461
3491
  end
@@ -4081,14 +4111,14 @@ module MarkdownExec
4081
4111
  end
4082
4112
  end
4083
4113
 
4084
- # Handle expression with wildcard characters
4085
- # allow user to select or enter
4086
- def puts_gets_oprompt_(filespec)
4087
- puts format(@delegate_object[:prompt_show_expr_format],
4088
- { expr: filespec })
4089
- puts @delegate_object[:prompt_enter_filespec]
4090
- gets.chomp
4091
- end
4114
+ # # Handle expression with wildcard characters
4115
+ # # allow user to select or enter
4116
+ # def puts_gets_oprompt_(filespec)
4117
+ # puts format(@delegate_object[:prompt_show_expr_format],
4118
+ # { expr: filespec })
4119
+ # puts @delegate_object[:prompt_enter_filespec]
4120
+ # gets.chomp
4121
+ # end
4092
4122
 
4093
4123
  def read_saved_assets_for_history_table(
4094
4124
  asset: nil,
@@ -4445,12 +4475,14 @@ module MarkdownExec
4445
4475
  # no enabled options in page
4446
4476
  return
4447
4477
  end
4478
+ ww 'selection', selection
4448
4479
 
4449
4480
  menu_list = opts.fetch(:match_dml, true) ? @dml_menu_blocks : menu_items
4450
4481
  menu_list ||= tty_menu_items
4451
4482
  selected = menu_list.find do |item|
4452
4483
  if item.instance_of?(Hash)
4453
- [item[:id], item[:name], item[:dname]].include?(selection)
4484
+ ### [item[:id], item[:name], item[:dname]].include?(selection)
4485
+ item[:id] == selection
4454
4486
  elsif item.instance_of?(MarkdownExec::FCB)
4455
4487
  item.id == selection
4456
4488
  else
@@ -4961,8 +4993,15 @@ module MarkdownExec
4961
4993
  command_result
4962
4994
  end
4963
4995
 
4964
- def warning_required_empty(export)
4965
- "A value must exist for: #{export.required.join(', ')}"
4996
+ # true if the variable is exported in a series of evaluations
4997
+ def variable_is_exportable(name)
4998
+ local_name_pattern = @delegate_object.fetch(:local_name_pattern, '')
4999
+
5000
+ # export all if rule is empty
5001
+ return true if local_name_pattern.empty?
5002
+
5003
+ # export if it its name does not match the rule
5004
+ !(name =~ Regexp.new(local_name_pattern))
4966
5005
  end
4967
5006
 
4968
5007
  def vux_await_user_selection(prior_answer: @dml_block_selection)
@@ -5263,9 +5302,14 @@ module MarkdownExec
5263
5302
  vux_user_selected_block_name
5264
5303
 
5265
5304
  when :execute_block
5266
- ret = vux_execute_block_per_type(data, formatted_choice_ostructs)
5267
- vux_publish_block_name_for_external_automation(data)
5268
- ret
5305
+ begin
5306
+ ret = vux_execute_block_per_type(data, formatted_choice_ostructs)
5307
+ vux_publish_block_name_for_external_automation(data)
5308
+ ret
5309
+ rescue StandardError
5310
+ # error executing block, do not abort
5311
+ InputSequencer.next_link_state(prior_block_was_link: false)
5312
+ end
5269
5313
 
5270
5314
  when :close_ux
5271
5315
  if @vux_pipe_open.present? && File.exist?(@vux_pipe_open)
@@ -5519,6 +5563,10 @@ module MarkdownExec
5519
5563
  determine_block_state(selected_option)
5520
5564
  end
5521
5565
 
5566
+ def warning_required_empty(export)
5567
+ "A value must exist for: #{export.required.join(', ')}"
5568
+ end
5569
+
5522
5570
  # Handles the core logic for generating the command
5523
5571
  # file's metadata and content.
5524
5572
  def write_command_file(required_lines:, blockname:, shell: nil)
@@ -1,3 +1,4 @@
1
+
1
2
  # frozen_string_literal: true
2
3
 
3
4
  # :reek:TooManyConstants
@@ -7,5 +8,5 @@ module MarkdownExec
7
8
  BIN_NAME = 'mde'
8
9
  GEM_NAME = 'markdown_exec'
9
10
  TAP_DEBUG = 'MDE_DEBUG'
10
- VERSION = '3.1.1'
11
+ VERSION = '3.2.0'
11
12
  end
data/lib/mdoc.rb CHANGED
@@ -119,7 +119,9 @@ module MarkdownExec
119
119
  raise "Named code block `#{anyname}` not found. (@#{__LINE__})"
120
120
  end
121
121
 
122
- nickname = name_block.pub_name
122
+ # nickname = name_block.pub_name
123
+ ####
124
+ nickname = name_block.id
123
125
 
124
126
  dependencies = collect_dependencies(pubname: nickname)
125
127
  # !!t dependencies.count
@@ -164,6 +166,8 @@ module MarkdownExec
164
166
  anyname:, block_source:,
165
167
  label_body: true, label_format_above: nil, label_format_below: nil
166
168
  )
169
+ ww 'anyname:', anyname
170
+ ww 'block_source:', block_source
167
171
  block_search = collect_block_dependencies(anyname: anyname)
168
172
  if block_search[:blocks]
169
173
  blocks = collect_wrapped_blocks(block_search[:blocks])
data/lib/menu.src.yml CHANGED
@@ -688,6 +688,12 @@
688
688
  :default: ''
689
689
  :procname: val_as_str
690
690
 
691
+ - :opt_name: local_name_pattern
692
+ :env_var: MDE_LOCAL_NAME_PATTERN
693
+ :description: Pattern for variables not exported in a series of evaluations
694
+ :default: '^.{1,3}$'
695
+ :procname: val_as_str
696
+
691
697
  - :opt_name: logged_stdout_filename_prefix
692
698
  :env_var: MDE_LOGGED_STDOUT_FILENAME_PREFIX
693
699
  :description: Name prefix for stdout files
@@ -1594,6 +1600,12 @@
1594
1600
  :default: 0
1595
1601
  :procname: val_as_int
1596
1602
 
1603
+ - :opt_name: select_page_ratio
1604
+ :env_var: MDE_SELECT_PAGE_RATIO
1605
+ :description: Number of lines of inactive text that require a scroll point, as a ratio of the page height.
1606
+ :default: 2
1607
+ :procname: val_as_int
1608
+
1597
1609
  - :opt_name: shebang
1598
1610
  :env_var: MDE_SHEBANG
1599
1611
  :description: Shebang for saved scripts
data/lib/menu.yml CHANGED
@@ -582,6 +582,11 @@
582
582
  :arg_name: PATH
583
583
  :default: ''
584
584
  :procname: val_as_str
585
+ - :opt_name: local_name_pattern
586
+ :env_var: MDE_LOCAL_NAME_PATTERN
587
+ :description: Pattern for variables not exported in a series of evaluations
588
+ :default: "^.{1,3}$"
589
+ :procname: val_as_str
585
590
  - :opt_name: logged_stdout_filename_prefix
586
591
  :env_var: MDE_LOGGED_STDOUT_FILENAME_PREFIX
587
592
  :description: Name prefix for stdout files
@@ -1362,6 +1367,12 @@
1362
1367
  :description: 'Maximum # of rows in select list. Detects current limit if not specified.'
1363
1368
  :default: 0
1364
1369
  :procname: val_as_int
1370
+ - :opt_name: select_page_ratio
1371
+ :env_var: MDE_SELECT_PAGE_RATIO
1372
+ :description: Number of lines of inactive text that require a scroll point, as a
1373
+ ratio of the page height.
1374
+ :default: 2
1375
+ :procname: val_as_int
1365
1376
  - :opt_name: shebang
1366
1377
  :env_var: MDE_SHEBANG
1367
1378
  :description: Shebang for saved scripts
data/lib/ww.rb CHANGED
@@ -26,7 +26,9 @@ end
26
26
  # select enabled, for exceptions
27
27
  # print a data object for the error, and the failing line
28
28
  def wwe(*objs, **kwargs)
29
- ww0(*objs, **kwargs.merge(locations: caller_locations[0..0]))
29
+ ww0(*objs,
30
+ **kwargs.merge(full_backtrace: true,
31
+ locations: caller_locations))
30
32
 
31
33
  raise StandardError, objs.first[:error]
32
34
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: markdown_exec
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.1
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fareed Stevenson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-06-28 00:00:00.000000000 Z
11
+ date: 2025-07-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard