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 +4 -4
- data/CHANGELOG.md +19 -0
- data/Gemfile.lock +1 -1
- data/docs/ux-blocks-examples.md +6 -5
- data/lib/fcb.rb +14 -2
- data/lib/hash_delegator.rb +73 -25
- data/lib/markdown_exec/version.rb +2 -1
- data/lib/mdoc.rb +5 -1
- data/lib/menu.src.yml +12 -0
- data/lib/menu.yml +11 -0
- data/lib/ww.rb +3 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c39aff829d6b7a3d4eb05134922cdb6fed1d54192fab72ba244d7d7ff73183e
|
4
|
+
data.tar.gz: f2bbfa6b9be857c718ba23c1bbc071b91ffe7ba027626c9a27b1d06c8bfce5a9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
data/docs/ux-blocks-examples.md
CHANGED
@@ -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:
|
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}@${
|
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:
|
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:
|
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
|
-
|
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[:
|
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|
|
data/lib/hash_delegator.rb
CHANGED
@@ -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
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
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
|
-
|
2668
|
-
|
2669
|
-
|
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.
|
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 %
|
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
|
-
|
4088
|
-
|
4089
|
-
|
4090
|
-
|
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
|
-
|
4965
|
-
|
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
|
-
|
5267
|
-
|
5268
|
-
|
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)
|
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,
|
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.
|
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-
|
11
|
+
date: 2025-07-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|