markdown_exec 2.8.1 → 2.8.2
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/.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
|