markdown_exec 2.8.1 → 2.8.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +27 -0
- data/Gemfile.lock +1 -1
- data/bats/block-hide.bats +8 -0
- data/bats/block-type-ux-require.bats +8 -0
- data/bin/tab_completion.sh +1 -1
- data/docs/dev/block-hide.md +18 -0
- data/docs/dev/block-type-ux-require.md +28 -0
- data/lib/fcb.rb +4 -1
- data/lib/hash_delegator.rb +242 -213
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +11 -28
- data/lib/mdoc.rb +5 -6
- data/lib/menu.src.yml +1 -0
- data/lib/menu.yml +1 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 066c72f2f85462a89163b7834669dee6526e516ee3ebfe4be2e8b269cb4ece36
|
4
|
+
data.tar.gz: 48c2bce9ac82cda2cbecca5bea4564b28013cdbab7005e249e8a856d0280afa0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe1270b8cf11efc8ad9e81cb43052bc75cfc217e362c7d6e30acb6981a6d0be749f290b9b15ce1a2655d6a7e157177c4cd975aa61de22a6f6bafe2a835285228
|
7
|
+
data.tar.gz: 9445285db86af55fe5ba0b784a24d30dd418ac3d1dc551183a5a1b3b865df27a6b314ddc08b4a013de5e926e023439753fe08cd4ea8d6c6da0c0d9547e4a9546
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,32 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.8.2] - 2025-02-19
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- UX blocks can add preconditions. Preconditions are variable names that must be set before the UX block is executed. If any preconditions are not set, a warning is displayed, and the sequence is aborted.
|
8
|
+
- UX blocks can require shell an other UX blocks.
|
9
|
+
- UX blocks are evaluated in order and calculation can depend on prior variables in the same sequence.
|
10
|
+
|
11
|
+
### Changed
|
12
|
+
|
13
|
+
- Hide all blocks per their initial title instead of `oname`.
|
14
|
+
- Make menu blocks for list of files found to fix crash.
|
15
|
+
- Use a block ID to recall the selected block.
|
16
|
+
- UX blocks are hidden similar to the rest.
|
17
|
+
|
18
|
+
## [2.8.1] - 2025-02-13
|
19
|
+
|
20
|
+
### Added
|
21
|
+
|
22
|
+
- BATS tests for UX block type.
|
23
|
+
|
24
|
+
### Changed
|
25
|
+
|
26
|
+
- Improve persistence of position in menu on reload
|
27
|
+
- Update block-type-ux-exec BATS test.
|
28
|
+
- Refactor menu for selecting items with facets.
|
29
|
+
|
3
30
|
## [2.8.0] - 2025-02-10
|
4
31
|
|
5
32
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
load 'test_helper'
|
4
|
+
|
5
|
+
@test 'Output of executed commands as initial value' {
|
6
|
+
spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-require.md \
|
7
|
+
'SPECIES=Pongo tapanuliensis_GENUS=Pongo_NAME=Pongo tapanuliensis - Pongo_NAME2=Pongo tapanuliensis - Pongo'
|
8
|
+
}
|
data/bin/tab_completion.sh
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
``` :(hidden)
|
2
|
+
```
|
3
|
+
``` :visible
|
4
|
+
```
|
5
|
+
/ ux block is displayed differently than other types
|
6
|
+
```ux :()
|
7
|
+
name: name
|
8
|
+
```
|
9
|
+
@import bats-document-configuration.md
|
10
|
+
```opts :(document_opts)
|
11
|
+
# Pattern for blocks to hide from user-selection
|
12
|
+
block_name_include_match:
|
13
|
+
^\(.*\)$
|
14
|
+
|
15
|
+
# Pattern for the block name in the line defining the block
|
16
|
+
block_name_match: |
|
17
|
+
:(?<title>\S+)( |$)
|
18
|
+
```
|
@@ -0,0 +1,28 @@
|
|
1
|
+
/ an automatic UX block requires a shell block and another UX block
|
2
|
+
``` :(shell)
|
3
|
+
ENTITY='Pongo tapanuliensis,Pongo'
|
4
|
+
```
|
5
|
+
```ux :[document_ux_SPECIES] +(shell) +[ux_GENUS]
|
6
|
+
default: :exec
|
7
|
+
exec: printf "${ENTITY%%,*}"
|
8
|
+
name: SPECIES
|
9
|
+
```
|
10
|
+
/ required ux block requires another
|
11
|
+
```ux :[ux_GENUS] +[ux_NAME]
|
12
|
+
default: :exec
|
13
|
+
exec: printf "${ENTITY##*,}"
|
14
|
+
name: GENUS
|
15
|
+
```
|
16
|
+
/ executed in context of prior ux blocks, uses their initial values
|
17
|
+
```ux :[ux_NAME]
|
18
|
+
default: :exec
|
19
|
+
exec: printf "$SPECIES - $GENUS"
|
20
|
+
name: NAME
|
21
|
+
```
|
22
|
+
/ executed after other ux blocks, uses their initial values
|
23
|
+
```ux :[document_ux_NAME2]
|
24
|
+
default: :exec
|
25
|
+
exec: printf "$NAME"
|
26
|
+
name: NAME2
|
27
|
+
```
|
28
|
+
@import bats-document-configuration.md
|
data/lib/fcb.rb
CHANGED
@@ -14,7 +14,8 @@ def parse_yaml_of_ux_block(
|
|
14
14
|
export = data['export']
|
15
15
|
export = data if export.nil?
|
16
16
|
name = export['name']
|
17
|
-
|
17
|
+
|
18
|
+
raise "Name is missing in UX block: #{data.inspect}" unless name.present?
|
18
19
|
|
19
20
|
OpenStruct.new(
|
20
21
|
allowed: export['allowed'],
|
@@ -22,6 +23,7 @@ def parse_yaml_of_ux_block(
|
|
22
23
|
exec: export['exec'],
|
23
24
|
menu_format: export['menu_format'] || menu_format,
|
24
25
|
name: name,
|
26
|
+
preconditions: export['preconditions'],
|
25
27
|
prompt: export['prompt'] || prompt,
|
26
28
|
transform: export['transform'],
|
27
29
|
validate: export['validate'] || validate
|
@@ -136,6 +138,7 @@ module MarkdownExec
|
|
136
138
|
@attrs[:center] = table_center
|
137
139
|
oname = @attrs[:oname] = format(export.menu_format, export.to_h)
|
138
140
|
else
|
141
|
+
# triggered by an empty block
|
139
142
|
raise "Invalid data type: #{data.inspect}"
|
140
143
|
end
|
141
144
|
end
|
data/lib/hash_delegator.rb
CHANGED
@@ -306,7 +306,7 @@ module HashDelegatorSelf
|
|
306
306
|
table__hs.each do |table_hs|
|
307
307
|
table_hs.substrings.each do |substrings|
|
308
308
|
substrings.each do |node|
|
309
|
-
next unless node[:text].
|
309
|
+
next unless node[:text].instance_of?(TrackedString)
|
310
310
|
|
311
311
|
exceeded_table_cell ||= node[:text].exceeded
|
312
312
|
truncated_table_cell = node[:text].truncated
|
@@ -606,6 +606,9 @@ module MarkdownExec
|
|
606
606
|
|
607
607
|
@process_mutex = Mutex.new
|
608
608
|
@process_cv = ConditionVariable.new
|
609
|
+
@dml_link_state = Struct.new(:document_filename, :inherited_lines)
|
610
|
+
.new(@delegate_object[:filename], [])
|
611
|
+
@dml_menu_blocks = []
|
609
612
|
|
610
613
|
@p_all_arguments = []
|
611
614
|
@p_options_parsed = []
|
@@ -1022,25 +1025,11 @@ module MarkdownExec
|
|
1022
1025
|
]
|
1023
1026
|
end
|
1024
1027
|
|
1025
|
-
|
1026
|
-
|
1027
|
-
# ww0 inherited_code
|
1028
|
-
code = (inherited_code || []) + [export_exec]
|
1029
|
-
filespec = generate_temp_filename
|
1030
|
-
File.write filespec, HashDelegator.join_code_lines(code)
|
1031
|
-
File.chmod 0o755, filespec
|
1032
|
-
# ww0 File.read(filespec)
|
1033
|
-
ret = `#{filespec}`
|
1034
|
-
File.delete filespec
|
1035
|
-
ret
|
1036
|
-
end
|
1037
|
-
|
1038
|
-
# sets ENV
|
1028
|
+
# parse YAML body defining the UX for a single variable
|
1029
|
+
# set ENV value for the variable and return code lines for the same
|
1039
1030
|
def code_from_ux_block_to_set_environment_variables(
|
1040
1031
|
selected, mdoc, inherited_code: nil, force: true, only_default: false
|
1041
1032
|
)
|
1042
|
-
# ww0 inherited_code
|
1043
|
-
# ww0 mdoc
|
1044
1033
|
exit_prompt = @delegate_object[:prompt_filespec_back]
|
1045
1034
|
|
1046
1035
|
required = mdoc.collect_recursively_required_code(
|
@@ -1050,105 +1039,106 @@ module MarkdownExec
|
|
1050
1039
|
block_source: block_source
|
1051
1040
|
)
|
1052
1041
|
|
1042
|
+
# process each ux block in sequence, setting ENV and collecting lines
|
1053
1043
|
code_lines = []
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
value = case export.default
|
1065
|
-
# exec > default
|
1066
|
-
when :exec
|
1067
|
-
raise unless export.exec.present?
|
1044
|
+
required[:blocks].each do |block|
|
1045
|
+
next unless block.type == BlockType::UX
|
1046
|
+
|
1047
|
+
case data = YAML.load(block.body.join("\n"))
|
1048
|
+
when Hash
|
1049
|
+
export = parse_yaml_of_ux_block(
|
1050
|
+
data,
|
1051
|
+
prompt: @delegate_object[:prompt_ux_enter_a_value],
|
1052
|
+
validate: '^(?<name>[^ ].*)$'
|
1053
|
+
)
|
1068
1054
|
|
1069
|
-
|
1070
|
-
|
1055
|
+
# preconditions are variable names that must be set before the UX block is executed.
|
1056
|
+
# if any precondition is not set, the sequence is aborted.
|
1057
|
+
export.preconditions&.each do |precondition|
|
1058
|
+
code_lines.push "[[ -z $#{precondition} ]] && exit 1"
|
1059
|
+
end
|
1071
1060
|
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
1080
|
-
|
1081
|
-
|
1061
|
+
exportable = true
|
1062
|
+
if only_default
|
1063
|
+
value = case export.default
|
1064
|
+
# exec > default
|
1065
|
+
when :exec
|
1066
|
+
raise unless export.exec.present?
|
1067
|
+
|
1068
|
+
output = export_exec_with_code(
|
1069
|
+
export, inherited_code, code_lines, required
|
1070
|
+
)
|
1071
|
+
if output == :invalidated
|
1072
|
+
return :ux_exec_prohibited
|
1082
1073
|
end
|
1074
|
+
|
1075
|
+
transform_export_value(output, export)
|
1076
|
+
# default
|
1083
1077
|
else
|
1084
|
-
|
1078
|
+
export.default.to_s
|
1085
1079
|
end
|
1080
|
+
else
|
1081
|
+
value = nil
|
1086
1082
|
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
# exec > allowed
|
1096
|
-
if export.exec
|
1097
|
-
value = neval(export.exec, (inherited_code || []) + required[:code])
|
1098
|
-
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1099
|
-
export.validate)
|
1100
|
-
|
1101
|
-
# allowed > prompt
|
1102
|
-
elsif export.allowed && export.allowed.count.positive?
|
1103
|
-
case (choice = prompt_select_code_filename(
|
1104
|
-
[exit_prompt] + export.allowed,
|
1105
|
-
string: export.prompt,
|
1106
|
-
color_sym: :prompt_color_after_script_execution
|
1107
|
-
))
|
1108
|
-
when exit_prompt
|
1109
|
-
exportable = false
|
1110
|
-
else
|
1111
|
-
value = choice
|
1112
|
-
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1113
|
-
export.validate)
|
1114
|
-
end
|
1115
|
-
|
1116
|
-
# prompt > default
|
1117
|
-
elsif export.prompt.present?
|
1118
|
-
begin
|
1119
|
-
while true
|
1120
|
-
print "#{export.prompt} [#{export.default}]: "
|
1121
|
-
value = gets.chomp
|
1122
|
-
value = export.default.to_s if value.empty?
|
1123
|
-
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1124
|
-
export.validate)
|
1125
|
-
break if caps
|
1083
|
+
# exec > allowed
|
1084
|
+
if export.exec
|
1085
|
+
value = export_exec_with_code(
|
1086
|
+
export, inherited_code, code_lines, required
|
1087
|
+
)
|
1088
|
+
if value == :invalidated
|
1089
|
+
return :ux_exec_prohibited
|
1090
|
+
end
|
1126
1091
|
|
1127
|
-
|
1092
|
+
# allowed > prompt
|
1093
|
+
elsif export.allowed && export.allowed.count.positive?
|
1094
|
+
case (choice = prompt_select_code_filename(
|
1095
|
+
[exit_prompt] + export.allowed,
|
1096
|
+
string: export.prompt,
|
1097
|
+
color_sym: :prompt_color_after_script_execution
|
1098
|
+
))
|
1099
|
+
when exit_prompt
|
1100
|
+
exportable = false
|
1101
|
+
else
|
1102
|
+
value = choice
|
1103
|
+
end
|
1128
1104
|
|
1105
|
+
# prompt > default
|
1106
|
+
elsif export.prompt.present?
|
1107
|
+
begin
|
1108
|
+
loop do
|
1109
|
+
print "#{export.prompt} [#{export.default}]: "
|
1110
|
+
value = gets.chomp
|
1111
|
+
value = export.default.to_s if value.empty?
|
1112
|
+
caps = NamedCaptureExtractor.extract_named_groups(value,
|
1113
|
+
export.validate)
|
1114
|
+
break if caps
|
1115
|
+
|
1116
|
+
# invalid input, retry
|
1117
|
+
end
|
1118
|
+
rescue Interrupt
|
1119
|
+
exportable = false
|
1129
1120
|
end
|
1130
|
-
|
1131
|
-
|
1121
|
+
|
1122
|
+
# default
|
1123
|
+
else
|
1124
|
+
value = export.default
|
1132
1125
|
end
|
1133
1126
|
|
1134
|
-
|
1135
|
-
|
1136
|
-
|
1127
|
+
if exportable
|
1128
|
+
value = transform_export_value(value, export)
|
1129
|
+
end
|
1137
1130
|
end
|
1138
1131
|
|
1139
|
-
if exportable
|
1140
|
-
|
1132
|
+
if exportable
|
1133
|
+
ENV[export.name] = value.to_s
|
1134
|
+
code_lines.push code_line_safe_assign(export.name, value,
|
1135
|
+
force: force)
|
1141
1136
|
end
|
1137
|
+
else
|
1138
|
+
raise "Invalid data type: #{data.inspect}"
|
1142
1139
|
end
|
1143
|
-
|
1144
|
-
if exportable
|
1145
|
-
ENV[export.name] = value.to_s
|
1146
|
-
code_lines.push code_line_safe_assign(export.name, value,
|
1147
|
-
force: force)
|
1148
|
-
end
|
1149
|
-
else
|
1150
|
-
raise "Invalid data type: #{data.inspect}"
|
1151
1140
|
end
|
1141
|
+
|
1152
1142
|
code_lines
|
1153
1143
|
end
|
1154
1144
|
|
@@ -1221,7 +1211,8 @@ module MarkdownExec
|
|
1221
1211
|
command_execute_in_process(
|
1222
1212
|
args: args, command: command,
|
1223
1213
|
erls: erls,
|
1224
|
-
filename: @delegate_object[:filename],
|
1214
|
+
filename: @delegate_object[:filename],
|
1215
|
+
shell: shell
|
1225
1216
|
)
|
1226
1217
|
end
|
1227
1218
|
|
@@ -1285,7 +1276,8 @@ module MarkdownExec
|
|
1285
1276
|
)
|
1286
1277
|
execute_command_with_streams(
|
1287
1278
|
[shell, '-c', command,
|
1288
|
-
@delegate_object[:filename],
|
1279
|
+
@delegate_object[:filename],
|
1280
|
+
*args]
|
1289
1281
|
)
|
1290
1282
|
end
|
1291
1283
|
|
@@ -1987,9 +1979,7 @@ module MarkdownExec
|
|
1987
1979
|
)
|
1988
1980
|
|
1989
1981
|
# dname is not fixed for some block types, use block id
|
1990
|
-
if lfls.load_file != LoadFile::LOAD
|
1991
|
-
[BlockType::HEADING, BlockType::TEXT,
|
1992
|
-
BlockType::UX].include?(selected.type)
|
1982
|
+
if lfls.load_file != LoadFile::LOAD
|
1993
1983
|
block_selection = BlockSelection.new(selected.id)
|
1994
1984
|
end
|
1995
1985
|
|
@@ -2173,24 +2163,24 @@ module MarkdownExec
|
|
2173
2163
|
else
|
2174
2164
|
warn 'No matching file found.'
|
2175
2165
|
end
|
2176
|
-
elsif selected_option = select_option_with_metadata(
|
2166
|
+
elsif (selected_option = select_option_with_metadata(
|
2177
2167
|
prompt_title,
|
2178
2168
|
[exit_prompt] + dirs.map do |file|
|
2179
|
-
{ name:
|
2180
|
-
|
2181
|
-
|
2182
|
-
|
2183
|
-
|
2184
|
-
|
2185
|
-
|
2186
|
-
|
2187
|
-
|
2169
|
+
{ name:
|
2170
|
+
format(
|
2171
|
+
block_data['view'] || view,
|
2172
|
+
NamedCaptureExtractor.extract_named_group_match_data(
|
2173
|
+
file.match(
|
2174
|
+
Regexp.new(block_data['filename_pattern'] || filename_pattern)
|
2175
|
+
)
|
2176
|
+
)
|
2177
|
+
),
|
2188
2178
|
oname: file }
|
2189
2179
|
end,
|
2190
2180
|
menu_options.merge(
|
2191
2181
|
cycle: true
|
2192
2182
|
)
|
2193
|
-
)
|
2183
|
+
))
|
2194
2184
|
if selected_option.dname != exit_prompt
|
2195
2185
|
File.readlines(selected_option.oname, chomp: true)
|
2196
2186
|
end
|
@@ -2341,7 +2331,7 @@ module MarkdownExec
|
|
2341
2331
|
|
2342
2332
|
interactive_menu_with_display_modes(
|
2343
2333
|
files_table_rows,
|
2344
|
-
display_formats: [
|
2334
|
+
display_formats: %i[row file],
|
2345
2335
|
display_mode_option: @delegate_object[:prompt_filespec_facet],
|
2346
2336
|
exit_option: exit_prompt,
|
2347
2337
|
menu_title: @delegate_object[:prompt_select_history_file],
|
@@ -2364,9 +2354,9 @@ module MarkdownExec
|
|
2364
2354
|
def execute_inherited_save(
|
2365
2355
|
code_lines: @dml_link_state.inherited_lines
|
2366
2356
|
)
|
2367
|
-
return unless save_filespec = save_filespec_from_expression
|
2368
|
-
|
2369
|
-
|
2357
|
+
return unless (save_filespec = save_filespec_from_expression)
|
2358
|
+
|
2359
|
+
document_name_in_glob_as_file_name
|
2370
2360
|
|
2371
2361
|
unless write_file_with_directory_creation(
|
2372
2362
|
content: HashDelegator.join_code_lines(code_lines),
|
@@ -2422,6 +2412,27 @@ module MarkdownExec
|
|
2422
2412
|
post_execution_process
|
2423
2413
|
end
|
2424
2414
|
|
2415
|
+
def execute_temporary_script(script_code, additional_code = [])
|
2416
|
+
full_code = (additional_code || []) + [script_code]
|
2417
|
+
|
2418
|
+
Tempfile.create('script_exec') do |temp_file|
|
2419
|
+
temp_file.write(HashDelegator.join_code_lines(full_code))
|
2420
|
+
temp_file.flush
|
2421
|
+
File.chmod(0o755, temp_file.path)
|
2422
|
+
|
2423
|
+
output = `#{temp_file.path}`
|
2424
|
+
|
2425
|
+
if $?.exitstatus != 0
|
2426
|
+
return :invalidated
|
2427
|
+
end
|
2428
|
+
|
2429
|
+
output
|
2430
|
+
end
|
2431
|
+
rescue StandardError => err
|
2432
|
+
warn "Error executing script: #{err.message}"
|
2433
|
+
nil
|
2434
|
+
end
|
2435
|
+
|
2425
2436
|
def expand_blocks_with_replacements(
|
2426
2437
|
menu_blocks, replacements, exclude_types: [BlockType::SHELL]
|
2427
2438
|
)
|
@@ -2468,6 +2479,18 @@ module MarkdownExec
|
|
2468
2479
|
expand_blocks_with_replacements(blocks, replacements)
|
2469
2480
|
end
|
2470
2481
|
|
2482
|
+
def export_exec_with_code(export, inherited_code, code_lines, required)
|
2483
|
+
value = execute_temporary_script(
|
2484
|
+
export.exec,
|
2485
|
+
(inherited_code || []) +
|
2486
|
+
code_lines + required[:code]
|
2487
|
+
)
|
2488
|
+
if value == :invalidated
|
2489
|
+
warn "A value must exist for: #{export.preconditions.join(', ')}"
|
2490
|
+
end
|
2491
|
+
value
|
2492
|
+
end
|
2493
|
+
|
2471
2494
|
# Retrieves a specific data symbol from the delegate object,
|
2472
2495
|
# converts it to a string, and applies a color style
|
2473
2496
|
# based on the specified color symbol.
|
@@ -2580,7 +2603,7 @@ module MarkdownExec
|
|
2580
2603
|
# commands to echo variables
|
2581
2604
|
#
|
2582
2605
|
commands = {}
|
2583
|
-
variable_counts.
|
2606
|
+
variable_counts.each_key do |variable|
|
2584
2607
|
command = format(echo_format, variable)
|
2585
2608
|
commands[variable] = command
|
2586
2609
|
end
|
@@ -2637,7 +2660,6 @@ module MarkdownExec
|
|
2637
2660
|
end
|
2638
2661
|
|
2639
2662
|
def history_files(
|
2640
|
-
link_state,
|
2641
2663
|
direction: :reverse,
|
2642
2664
|
filename: nil,
|
2643
2665
|
home: Dir.pwd,
|
@@ -2950,19 +2972,24 @@ module MarkdownExec
|
|
2950
2972
|
@ux_most_recent_filename = @delegate_object[:filename]
|
2951
2973
|
|
2952
2974
|
(blocks.each.with_object([]) do |block, merged_options|
|
2953
|
-
|
2954
|
-
|
2955
|
-
|
2956
|
-
|
2957
|
-
|
2958
|
-
only_default: true
|
2959
|
-
)
|
2975
|
+
code = code_from_ux_block_to_set_environment_variables(
|
2976
|
+
block,
|
2977
|
+
mdoc,
|
2978
|
+
force: @delegate_object[:ux_auto_load_force_default],
|
2979
|
+
only_default: true
|
2960
2980
|
)
|
2981
|
+
if code == :ux_exec_prohibited
|
2982
|
+
merged_options
|
2983
|
+
else
|
2984
|
+
merged_options.push(code)
|
2985
|
+
end
|
2961
2986
|
end).to_a
|
2962
2987
|
end
|
2963
2988
|
|
2964
|
-
def load_auto_vars_block(
|
2965
|
-
|
2989
|
+
def load_auto_vars_block(
|
2990
|
+
all_blocks,
|
2991
|
+
block_name: @delegate_object[:document_load_vars_block_name]
|
2992
|
+
)
|
2966
2993
|
unless block_name.present? &&
|
2967
2994
|
@vars_most_recent_filename != @delegate_object[:filename]
|
2968
2995
|
return
|
@@ -3103,7 +3130,7 @@ module MarkdownExec
|
|
3103
3130
|
|
3104
3131
|
# load document shell block
|
3105
3132
|
#
|
3106
|
-
if code_lines = load_document_shell_block(all_blocks, mdoc: mdoc)
|
3133
|
+
if (code_lines = load_document_shell_block(all_blocks, mdoc: mdoc))
|
3107
3134
|
next_state_set_code(nil, link_state, code_lines)
|
3108
3135
|
link_state.inherited_lines = code_lines
|
3109
3136
|
reload_blocks = true
|
@@ -3111,7 +3138,7 @@ module MarkdownExec
|
|
3111
3138
|
|
3112
3139
|
# load document ux block
|
3113
3140
|
#
|
3114
|
-
if code_lines = load_auto_ux_block(all_blocks, mdoc)
|
3141
|
+
if (code_lines = load_auto_ux_block(all_blocks, mdoc))
|
3115
3142
|
new_code = HashDelegator.code_merge(link_state.inherited_lines,
|
3116
3143
|
code_lines)
|
3117
3144
|
next_state_set_code(nil, link_state, new_code)
|
@@ -3121,7 +3148,7 @@ module MarkdownExec
|
|
3121
3148
|
|
3122
3149
|
# load document vars block
|
3123
3150
|
#
|
3124
|
-
if code_lines = load_auto_vars_block(all_blocks)
|
3151
|
+
if (code_lines = load_auto_vars_block(all_blocks))
|
3125
3152
|
new_code = HashDelegator.code_merge(link_state.inherited_lines,
|
3126
3153
|
code_lines)
|
3127
3154
|
next_state_set_code(nil, link_state, new_code)
|
@@ -3267,7 +3294,10 @@ module MarkdownExec
|
|
3267
3294
|
next_state_set_code(
|
3268
3295
|
selected,
|
3269
3296
|
link_state,
|
3270
|
-
HashDelegator.code_merge(
|
3297
|
+
HashDelegator.code_merge(
|
3298
|
+
link_state&.inherited_lines,
|
3299
|
+
code_lines.is_a?(Array) ? code_lines : [] # no code for :ux_exec_prohibited
|
3300
|
+
)
|
3271
3301
|
)
|
3272
3302
|
end
|
3273
3303
|
|
@@ -3409,8 +3439,8 @@ module MarkdownExec
|
|
3409
3439
|
#
|
3410
3440
|
# @param all_blocks [Array<Hash>] The list of blocks from the file.
|
3411
3441
|
def select_blocks(menu_blocks)
|
3412
|
-
menu_blocks.
|
3413
|
-
|
3442
|
+
menu_blocks.reject do |fcb|
|
3443
|
+
Filter.prepared_not_in_menu?(
|
3414
3444
|
@delegate_object,
|
3415
3445
|
fcb,
|
3416
3446
|
%i[block_name_include_match block_name_wrapper_match]
|
@@ -3659,16 +3689,16 @@ module MarkdownExec
|
|
3659
3689
|
|
3660
3690
|
case @delegate_object[:publish_document_file_mode]
|
3661
3691
|
when 'append'
|
3662
|
-
File.write(pipe_path, message
|
3692
|
+
File.write(pipe_path, "#{message}\n", mode: 'a')
|
3663
3693
|
when 'fifo'
|
3664
3694
|
unless @vux_pipe_open
|
3665
3695
|
unless File.exist?(pipe_path)
|
3666
|
-
|
3696
|
+
File.mkfifo(pipe_path)
|
3667
3697
|
@vux_pipe_created = pipe_path
|
3668
3698
|
end
|
3669
3699
|
@vux_pipe_open = File.open(pipe_path, 'w')
|
3670
3700
|
end
|
3671
|
-
@vux_pipe_open.puts(message
|
3701
|
+
@vux_pipe_open.puts("#{message}\n")
|
3672
3702
|
@vux_pipe_open.flush
|
3673
3703
|
when 'write'
|
3674
3704
|
File.write(pipe_path, message)
|
@@ -3695,7 +3725,6 @@ module MarkdownExec
|
|
3695
3725
|
regexp: @delegate_object[:saved_asset_match]
|
3696
3726
|
)
|
3697
3727
|
history_files(
|
3698
|
-
@dml_link_state,
|
3699
3728
|
filename:
|
3700
3729
|
if asset.present?
|
3701
3730
|
saved_asset_filename(asset, @dml_link_state)
|
@@ -3710,7 +3739,8 @@ module MarkdownExec
|
|
3710
3739
|
end
|
3711
3740
|
|
3712
3741
|
saved_asset = saved_asset_for_history(
|
3713
|
-
file: file,
|
3742
|
+
file: file,
|
3743
|
+
form: form,
|
3714
3744
|
match_info: $LAST_MATCH_INFO
|
3715
3745
|
)
|
3716
3746
|
saved_asset == :break ? nil : saved_asset
|
@@ -3959,7 +3989,7 @@ module MarkdownExec
|
|
3959
3989
|
|
3960
3990
|
def screen_width
|
3961
3991
|
width = @delegate_object[:screen_width]
|
3962
|
-
if width
|
3992
|
+
if width&.positive?
|
3963
3993
|
width
|
3964
3994
|
else
|
3965
3995
|
@delegate_object[:console_width]
|
@@ -3976,7 +4006,7 @@ module MarkdownExec
|
|
3976
4006
|
end
|
3977
4007
|
|
3978
4008
|
def select_document_if_multiple(options, files, prompt:)
|
3979
|
-
return files if files.
|
4009
|
+
return files if files.instance_of?(String)
|
3980
4010
|
return files[0] if (count = files.count) == 1
|
3981
4011
|
|
3982
4012
|
return unless count >= 2
|
@@ -3994,7 +4024,11 @@ module MarkdownExec
|
|
3994
4024
|
|
3995
4025
|
# Presents a TTY prompt to select an option or exit,
|
3996
4026
|
# returns metadata including option and selected
|
3997
|
-
def select_option_with_metadata(
|
4027
|
+
def select_option_with_metadata(
|
4028
|
+
prompt_text, menu_items, opts = {}, menu_blocks: nil
|
4029
|
+
)
|
4030
|
+
@dml_menu_blocks = menu_blocks if menu_blocks
|
4031
|
+
|
3998
4032
|
## configure to environment
|
3999
4033
|
#
|
4000
4034
|
register_console_attributes(opts)
|
@@ -4039,23 +4073,16 @@ module MarkdownExec
|
|
4039
4073
|
return
|
4040
4074
|
end
|
4041
4075
|
|
4042
|
-
selected =
|
4076
|
+
selected = @dml_menu_blocks.find do |item|
|
4043
4077
|
if item.instance_of?(Hash)
|
4044
4078
|
[item[:id], item[:name], item[:dname]].include?(selection)
|
4045
4079
|
elsif item.instance_of?(MarkdownExec::FCB)
|
4046
|
-
item.
|
4080
|
+
item.id == selection
|
4047
4081
|
else
|
4048
4082
|
item == selection
|
4049
4083
|
end
|
4050
4084
|
end
|
4051
4085
|
|
4052
|
-
# new FCB if selected is not an object
|
4053
|
-
if selected.instance_of?(String)
|
4054
|
-
selected = FCB.new(dname: selected)
|
4055
|
-
elsif selected.instance_of?(Hash)
|
4056
|
-
selected = FCB.new(selected)
|
4057
|
-
end
|
4058
|
-
|
4059
4086
|
unless selected
|
4060
4087
|
HashDelegator.error_handler('select_option_with_metadata',
|
4061
4088
|
error: 'menu item not found')
|
@@ -4206,6 +4233,21 @@ module MarkdownExec
|
|
4206
4233
|
HashDelegator.apply_color_from_hash(string, @delegate_object, color_sym)
|
4207
4234
|
end
|
4208
4235
|
|
4236
|
+
def transform_export_value(value, export)
|
4237
|
+
return value unless export.transform.present?
|
4238
|
+
|
4239
|
+
if export.transform.is_a? Symbol
|
4240
|
+
value.send(export.transform)
|
4241
|
+
else
|
4242
|
+
format(
|
4243
|
+
export.transform,
|
4244
|
+
NamedCaptureExtractor.extract_named_groups(
|
4245
|
+
value, export.validate
|
4246
|
+
)
|
4247
|
+
)
|
4248
|
+
end
|
4249
|
+
end
|
4250
|
+
|
4209
4251
|
##
|
4210
4252
|
# Processes an individual line within a loop, updating headings
|
4211
4253
|
# and handling fenced code blocks.
|
@@ -4372,7 +4414,7 @@ module MarkdownExec
|
|
4372
4414
|
|
4373
4415
|
when formatted_choice_ostructs[:history].pub_name
|
4374
4416
|
debounce_reset
|
4375
|
-
return :break unless files_table_rows = vux_history_files_table_rows
|
4417
|
+
return :break unless (files_table_rows = vux_history_files_table_rows)
|
4376
4418
|
|
4377
4419
|
execute_history_select(files_table_rows, stream: $stderr)
|
4378
4420
|
return :break if pause_user_exit
|
@@ -4498,9 +4540,9 @@ module MarkdownExec
|
|
4498
4540
|
end
|
4499
4541
|
|
4500
4542
|
def vux_load_inherited
|
4501
|
-
return unless filespec = load_filespec_from_expression(
|
4543
|
+
return unless (filespec = load_filespec_from_expression(
|
4502
4544
|
document_name_in_glob_as_file_name
|
4503
|
-
)
|
4545
|
+
))
|
4504
4546
|
|
4505
4547
|
@dml_link_state.inherited_lines_append(
|
4506
4548
|
File.readlines(filespec, chomp: true)
|
@@ -4619,7 +4661,6 @@ module MarkdownExec
|
|
4619
4661
|
)
|
4620
4662
|
if @delegate_object[:menu_for_history]
|
4621
4663
|
history_files(
|
4622
|
-
@dml_link_state,
|
4623
4664
|
filename: saved_asset_filename(@delegate_object[:filename],
|
4624
4665
|
@dml_link_state),
|
4625
4666
|
path: @delegate_object[:saved_script_folder]
|
@@ -4818,15 +4859,17 @@ module MarkdownExec
|
|
4818
4859
|
menu_blocks.find do |block|
|
4819
4860
|
block.dname.include?(prior_answer)
|
4820
4861
|
end&.name
|
4821
|
-
when Struct
|
4862
|
+
when Struct, MarkdownExec::FCB
|
4822
4863
|
if prior_answer.id
|
4823
|
-
|
4864
|
+
# when switching documents, the prior answer will not be found
|
4865
|
+
(menu_blocks.find_index do |block|
|
4824
4866
|
block[:id] == prior_answer.id
|
4825
|
-
end + 1
|
4867
|
+
end || 0) + 1
|
4826
4868
|
else
|
4827
4869
|
prior_answer.index || prior_answer.name
|
4828
4870
|
end
|
4829
4871
|
end
|
4872
|
+
|
4830
4873
|
# prior_answer value may not match if color is different from
|
4831
4874
|
# originating menu (opts changed while processing)
|
4832
4875
|
selection_opts = if selected_answer
|
@@ -5157,13 +5200,12 @@ module MarkdownExec
|
|
5157
5200
|
|
5158
5201
|
class TestHashDelegatorAppendDivider < Minitest::Test
|
5159
5202
|
def setup
|
5160
|
-
@hd = HashDelegator.new
|
5161
|
-
|
5162
|
-
|
5163
|
-
|
5164
|
-
|
5165
|
-
|
5166
|
-
})
|
5203
|
+
@hd = HashDelegator.new(
|
5204
|
+
menu_divider_color: :color,
|
5205
|
+
menu_divider_format: 'Format',
|
5206
|
+
menu_final_divider: 'Final Divider',
|
5207
|
+
menu_initial_divider: 'Initial Divider'
|
5208
|
+
)
|
5167
5209
|
@hd.stubs(:string_send_color).returns('Formatted Divider')
|
5168
5210
|
HashDelegator.stubs(:safeval).returns('Safe Value')
|
5169
5211
|
end
|
@@ -5185,7 +5227,7 @@ module MarkdownExec
|
|
5185
5227
|
end
|
5186
5228
|
|
5187
5229
|
def test_append_divider_without_format
|
5188
|
-
@hd.
|
5230
|
+
@hd = HashDelegator.new
|
5189
5231
|
menu_blocks = []
|
5190
5232
|
@hd.append_divider(menu_blocks: menu_blocks, position: :initial)
|
5191
5233
|
|
@@ -5223,7 +5265,6 @@ module MarkdownExec
|
|
5223
5265
|
@hd = HashDelegator.new
|
5224
5266
|
@hd.stubs(:iter_blocks_from_nested_files).yields(:blocks, FCB.new)
|
5225
5267
|
@hd.stubs(:create_and_add_chrome_blocks)
|
5226
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5227
5268
|
HashDelegator.stubs(:error_handler)
|
5228
5269
|
end
|
5229
5270
|
|
@@ -5234,7 +5275,7 @@ module MarkdownExec
|
|
5234
5275
|
end
|
5235
5276
|
|
5236
5277
|
def test_blocks_from_nested_files_with_no_chrome
|
5237
|
-
@hd.
|
5278
|
+
@hd = HashDelegator.new(no_chrome: true)
|
5238
5279
|
@hd.expects(:create_and_add_chrome_blocks).never
|
5239
5280
|
|
5240
5281
|
result = @hd.blocks_from_nested_files
|
@@ -5246,7 +5287,6 @@ module MarkdownExec
|
|
5246
5287
|
class TestHashDelegatorCollectRequiredCodeLines < Minitest::Test
|
5247
5288
|
def setup
|
5248
5289
|
@hd = HashDelegator.new
|
5249
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5250
5290
|
@mdoc = mock('YourMDocClass')
|
5251
5291
|
@selected = FCB.new(
|
5252
5292
|
body: ['key: value'],
|
@@ -5272,15 +5312,13 @@ module MarkdownExec
|
|
5272
5312
|
class TestHashDelegatorCommandOrUserSelectedBlock < Minitest::Test
|
5273
5313
|
def setup
|
5274
5314
|
@hd = HashDelegator.new
|
5275
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5276
5315
|
HashDelegator.stubs(:error_handler)
|
5277
5316
|
@hd.stubs(:wait_for_user_selected_block)
|
5278
5317
|
end
|
5279
5318
|
|
5280
5319
|
def test_command_selected_block
|
5281
5320
|
all_blocks = [{ oname: 'block1' }, { oname: 'block2' }]
|
5282
|
-
@hd.
|
5283
|
-
{ block_name: 'block1' })
|
5321
|
+
@hd = HashDelegator.new(block_name: 'block1')
|
5284
5322
|
|
5285
5323
|
result = @hd.load_cli_or_user_selected_block(all_blocks: all_blocks)
|
5286
5324
|
|
@@ -5309,10 +5347,10 @@ module MarkdownExec
|
|
5309
5347
|
|
5310
5348
|
class TestHashDelegatorCountBlockInFilename < Minitest::Test
|
5311
5349
|
def setup
|
5312
|
-
@hd = HashDelegator.new
|
5313
|
-
|
5314
|
-
|
5315
|
-
|
5350
|
+
@hd = HashDelegator.new(
|
5351
|
+
fenced_start_and_end_regex: '^```',
|
5352
|
+
filename: '/path/to/file'
|
5353
|
+
)
|
5316
5354
|
@hd.stubs(:cfile).returns(mock('cfile'))
|
5317
5355
|
end
|
5318
5356
|
|
@@ -5421,7 +5459,6 @@ module MarkdownExec
|
|
5421
5459
|
def setup
|
5422
5460
|
@hd = HashDelegator.new
|
5423
5461
|
@hd.instance_variable_set(:@fout, mock('fout'))
|
5424
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5425
5462
|
@hd.stubs(:string_send_color)
|
5426
5463
|
end
|
5427
5464
|
|
@@ -5443,7 +5480,6 @@ module MarkdownExec
|
|
5443
5480
|
class TestHashDelegatorFetchColor < Minitest::Test
|
5444
5481
|
def setup
|
5445
5482
|
@hd = HashDelegator.new
|
5446
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5447
5483
|
end
|
5448
5484
|
|
5449
5485
|
def test_fetch_color_with_valid_data
|
@@ -5476,7 +5512,6 @@ module MarkdownExec
|
|
5476
5512
|
class TestHashDelegatorFormatReferencesSendColor < Minitest::Test
|
5477
5513
|
def setup
|
5478
5514
|
@hd = HashDelegator.new
|
5479
|
-
@hd.instance_variable_set(:@delegate_object, {})
|
5480
5515
|
end
|
5481
5516
|
|
5482
5517
|
def test_format_references_send_color_with_valid_data
|
@@ -5581,7 +5616,6 @@ module MarkdownExec
|
|
5581
5616
|
# )
|
5582
5617
|
|
5583
5618
|
# def history_files(
|
5584
|
-
# link_state,
|
5585
5619
|
# direction: :reverse,
|
5586
5620
|
# filename: nil,
|
5587
5621
|
# home: Dir.pwd,
|
@@ -5590,9 +5624,10 @@ module MarkdownExec
|
|
5590
5624
|
# )
|
5591
5625
|
|
5592
5626
|
def test_call
|
5593
|
-
@hd.expects(:history_files).with(
|
5594
|
-
@hd.execute_block_type_history_ux(
|
5595
|
-
|
5627
|
+
@hd.expects(:history_files).with(filename: '*', path: nil).once
|
5628
|
+
@hd.execute_block_type_history_ux(
|
5629
|
+
filename: '*', link_state: LinkState.new, selected: FCB.new(body: [])
|
5630
|
+
)
|
5596
5631
|
end
|
5597
5632
|
end
|
5598
5633
|
|
@@ -5677,11 +5712,9 @@ module MarkdownExec
|
|
5677
5712
|
|
5678
5713
|
class TestHashDelegatorHandleStream < Minitest::Test
|
5679
5714
|
def setup
|
5680
|
-
@hd = HashDelegator.new
|
5715
|
+
@hd = HashDelegator.new(output_stdout: true)
|
5681
5716
|
@hd.instance_variable_set(:@run_state,
|
5682
5717
|
OpenStruct.new(files: StreamsOut.new))
|
5683
|
-
@hd.instance_variable_set(:@delegate_object,
|
5684
|
-
{ output_stdout: true })
|
5685
5718
|
end
|
5686
5719
|
|
5687
5720
|
def test_handle_stream
|
@@ -5713,9 +5746,7 @@ module MarkdownExec
|
|
5713
5746
|
|
5714
5747
|
class TestHashDelegatorIterBlocksFromNestedFiles < Minitest::Test
|
5715
5748
|
def setup
|
5716
|
-
@hd = HashDelegator.new
|
5717
|
-
@hd.instance_variable_set(:@delegate_object,
|
5718
|
-
{ filename: 'test.md' })
|
5749
|
+
@hd = HashDelegator.new(filename: 'test.md')
|
5719
5750
|
@hd.stubs(:check_file_existence).with('test.md').returns(true)
|
5720
5751
|
@hd.stubs(:initial_state).returns({})
|
5721
5752
|
@hd.stubs(:cfile).returns(Minitest::Mock.new)
|
@@ -5744,12 +5775,11 @@ module MarkdownExec
|
|
5744
5775
|
|
5745
5776
|
class TestHashDelegatorMenuChromeColoredOption < Minitest::Test
|
5746
5777
|
def setup
|
5747
|
-
@hd = HashDelegator.new
|
5748
|
-
|
5749
|
-
|
5750
|
-
|
5751
|
-
|
5752
|
-
})
|
5778
|
+
@hd = HashDelegator.new(
|
5779
|
+
menu_chrome_color: :red,
|
5780
|
+
menu_chrome_format: '-- %s --',
|
5781
|
+
menu_option_back_name: 'Back'
|
5782
|
+
)
|
5753
5783
|
@hd.stubs(:menu_chrome_formatted_option)
|
5754
5784
|
.with(:menu_option_back_name).returns('-- Back --')
|
5755
5785
|
@hd.stubs(:string_send_color)
|
@@ -5763,8 +5793,9 @@ module MarkdownExec
|
|
5763
5793
|
end
|
5764
5794
|
|
5765
5795
|
def test_menu_chrome_colored_option_without_color
|
5766
|
-
@hd.
|
5767
|
-
|
5796
|
+
@hd = HashDelegator.new(menu_option_back_name: 'Back')
|
5797
|
+
@hd.stubs(:menu_chrome_formatted_option)
|
5798
|
+
.with(:menu_option_back_name).returns('-- Back --')
|
5768
5799
|
assert_equal '-- Back --',
|
5769
5800
|
@hd.menu_chrome_colored_option(:menu_option_back_name)
|
5770
5801
|
end
|
@@ -5772,11 +5803,10 @@ module MarkdownExec
|
|
5772
5803
|
|
5773
5804
|
class TestHashDelegatorMenuChromeOption < Minitest::Test
|
5774
5805
|
def setup
|
5775
|
-
@hd = HashDelegator.new
|
5776
|
-
|
5777
|
-
|
5778
|
-
|
5779
|
-
})
|
5806
|
+
@hd = HashDelegator.new(
|
5807
|
+
menu_chrome_format: '-- %s --',
|
5808
|
+
menu_option_back_name: "'Back'"
|
5809
|
+
)
|
5780
5810
|
HashDelegator.stubs(:safeval).with("'Back'").returns('Back')
|
5781
5811
|
end
|
5782
5812
|
|
@@ -5786,8 +5816,7 @@ module MarkdownExec
|
|
5786
5816
|
end
|
5787
5817
|
|
5788
5818
|
def test_menu_chrome_formatted_option_without_format
|
5789
|
-
@hd.
|
5790
|
-
{ menu_option_back_name: "'Back'" })
|
5819
|
+
@hd = HashDelegator.new(menu_option_back_name: "'Back'")
|
5791
5820
|
assert_equal 'Back',
|
5792
5821
|
@hd.menu_chrome_formatted_option(:menu_option_back_name)
|
5793
5822
|
end
|
@@ -5795,10 +5824,12 @@ module MarkdownExec
|
|
5795
5824
|
|
5796
5825
|
class TestHashDelegatorStartFencedBlock < Minitest::Test
|
5797
5826
|
def setup
|
5798
|
-
@hd = HashDelegator.new(
|
5799
|
-
|
5800
|
-
|
5801
|
-
|
5827
|
+
@hd = HashDelegator.new(
|
5828
|
+
{
|
5829
|
+
block_calls_scan: 'CALLS_REGEX',
|
5830
|
+
block_name_wrapper_match: 'WRAPPER_REGEX'
|
5831
|
+
}
|
5832
|
+
)
|
5802
5833
|
end
|
5803
5834
|
|
5804
5835
|
def test_start_fenced_block
|
@@ -5816,9 +5847,7 @@ module MarkdownExec
|
|
5816
5847
|
|
5817
5848
|
class TestHashDelegatorStringSendColor < Minitest::Test
|
5818
5849
|
def setup
|
5819
|
-
@hd = HashDelegator.new
|
5820
|
-
@hd.instance_variable_set(:@delegate_object,
|
5821
|
-
{ red: 'red', green: 'green' })
|
5850
|
+
@hd = HashDelegator.new(red: 'red', green: 'green')
|
5822
5851
|
end
|
5823
5852
|
|
5824
5853
|
def test_string_send_color
|
data/lib/markdown_exec.rb
CHANGED
@@ -656,32 +656,6 @@ module MarkdownExec
|
|
656
656
|
@options.merge(@options.run_state.to_h)
|
657
657
|
end
|
658
658
|
|
659
|
-
def iter_source_blocks(source, &block)
|
660
|
-
case source
|
661
|
-
when 1
|
662
|
-
HashDelegator.new(@options).blocks_from_nested_files.each(&block)
|
663
|
-
when 2
|
664
|
-
blocks_in_file, menu_blocks, mdoc =
|
665
|
-
HashDelegator.new(@options)
|
666
|
-
.mdoc_menu_and_blocks_from_nested_files(LinkState.new)
|
667
|
-
blocks_in_file.each(&block)
|
668
|
-
when 3
|
669
|
-
blocks_in_file, menu_blocks, mdoc =
|
670
|
-
HashDelegator.new(@options)
|
671
|
-
.mdoc_menu_and_blocks_from_nested_files(LinkState.new)
|
672
|
-
menu_blocks.each(&block)
|
673
|
-
else
|
674
|
-
@options.iter_blocks_from_nested_files do |btype, fcb|
|
675
|
-
case btype
|
676
|
-
when :blocks
|
677
|
-
yield fcb
|
678
|
-
when :filter
|
679
|
-
%i[blocks]
|
680
|
-
end
|
681
|
-
end
|
682
|
-
end
|
683
|
-
end
|
684
|
-
|
685
659
|
##
|
686
660
|
# Returns a lambda expression based on the given procname.
|
687
661
|
# @param procname [String] The name of the process to generate a lambda for.
|
@@ -916,7 +890,7 @@ module MarkdownExec
|
|
916
890
|
# save value to options hash if option is named
|
917
891
|
#
|
918
892
|
lambda { |value|
|
919
|
-
name = item[:long_name]&.present? ?
|
893
|
+
name = item[:long_name]&.present? ? "--#{item[:long_name]}" : "-#{item[:short_name]}"
|
920
894
|
options_parsed << item.merge(name: name, value: value)
|
921
895
|
(item[:proccode] ? item[:proccode].call(value) : value).tap do |converted|
|
922
896
|
options[item[:opt_name]] = converted if item[:opt_name]
|
@@ -1013,7 +987,16 @@ module MarkdownExec
|
|
1013
987
|
# Presents a TTY prompt to select an option or exit, returns selected option or nil
|
1014
988
|
def select_option_or_exit(prompt_text, strings, opts = {})
|
1015
989
|
@options.select_option_with_metadata(
|
1016
|
-
prompt_text,
|
990
|
+
prompt_text,
|
991
|
+
strings,
|
992
|
+
opts,
|
993
|
+
menu_blocks: strings.map do |string|
|
994
|
+
FCB.new(
|
995
|
+
chrome: true,
|
996
|
+
dname: string,
|
997
|
+
id: string
|
998
|
+
)
|
999
|
+
end
|
1017
1000
|
)&.fetch(:selected)
|
1018
1001
|
end
|
1019
1002
|
|
data/lib/mdoc.rb
CHANGED
@@ -355,13 +355,12 @@ module MarkdownExec
|
|
355
355
|
else
|
356
356
|
opts[:hide_blocks_by_name] &&
|
357
357
|
((opts[:block_name_hidden_match]&.present? &&
|
358
|
-
block.
|
358
|
+
block.s2title&.match(Regexp.new(opts[:block_name_hidden_match]))) ||
|
359
359
|
(opts[:block_name_include_match]&.present? &&
|
360
|
-
block.
|
360
|
+
block.s2title&.match(Regexp.new(opts[:block_name_include_match]))) ||
|
361
361
|
(opts[:block_name_wrapper_match]&.present? &&
|
362
|
-
block.
|
363
|
-
(block.
|
364
|
-
|
362
|
+
block.s2title&.match(Regexp.new(opts[:block_name_wrapper_match])))) &&
|
363
|
+
(block.s2title&.present? || block[:label]&.present?)
|
365
364
|
end
|
366
365
|
end
|
367
366
|
|
@@ -555,7 +554,7 @@ if $PROGRAM_NAME == __FILE__
|
|
555
554
|
def test_hide_menu_block_on_name
|
556
555
|
opts = { hide_blocks_by_name: true,
|
557
556
|
block_name_hidden_match: 'block1' }
|
558
|
-
block = FCB.new(
|
557
|
+
block = FCB.new(s2title: 'block1')
|
559
558
|
result = @doc.hide_menu_block_on_name(opts, block)
|
560
559
|
assert result # this should be true based on the given logic
|
561
560
|
end
|
data/lib/menu.src.yml
CHANGED
data/lib/menu.yml
CHANGED
@@ -44,6 +44,7 @@
|
|
44
44
|
:procname: val_as_str
|
45
45
|
- :opt_name: block_name_match
|
46
46
|
:env_var: MDE_BLOCK_NAME_MATCH
|
47
|
+
:description: Pattern for the block name in the line defining the block
|
47
48
|
:default: ":(?<title>\\S+)( |$)"
|
48
49
|
:procname: val_as_str
|
49
50
|
- :opt_name: block_name_nick_match
|
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: 2.8.
|
4
|
+
version: 2.8.2
|
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-02-
|
11
|
+
date: 2025-02-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|
@@ -107,9 +107,11 @@ files:
|
|
107
107
|
- assets/select_a_block.png
|
108
108
|
- assets/select_a_file.png
|
109
109
|
- bats/bats.bats
|
110
|
+
- bats/block-hide.bats
|
110
111
|
- bats/block-type-opts.bats
|
111
112
|
- bats/block-type-ux-auto.bats
|
112
113
|
- bats/block-type-ux-exec.bats
|
114
|
+
- bats/block-type-ux-require.bats
|
113
115
|
- bats/block-type-ux-row-format.bats
|
114
116
|
- bats/block-type-ux-transform.bats
|
115
117
|
- bats/block-type-vars.bats
|
@@ -140,11 +142,13 @@ files:
|
|
140
142
|
- bin/tab_completion.sh
|
141
143
|
- bin/tab_completion.sh.erb
|
142
144
|
- docs/dev/bats-document-configuration.md
|
145
|
+
- docs/dev/block-hide.md
|
143
146
|
- docs/dev/block-type-bash.md
|
144
147
|
- docs/dev/block-type-opts.md
|
145
148
|
- docs/dev/block-type-port.md
|
146
149
|
- docs/dev/block-type-ux-auto.md
|
147
150
|
- docs/dev/block-type-ux-exec.md
|
151
|
+
- docs/dev/block-type-ux-require.md
|
148
152
|
- docs/dev/block-type-ux-row-format.md
|
149
153
|
- docs/dev/block-type-ux-transform.md
|
150
154
|
- docs/dev/block-type-vars.md
|