markdown_exec 2.8.4 → 2.8.5
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 +15 -0
- data/Gemfile.lock +1 -1
- data/bats/block-type-ux-default.bats +8 -0
- data/docs/dev/block-type-ux-allowed.md +2 -0
- data/docs/dev/block-type-ux-auto.md +2 -1
- data/docs/dev/block-type-ux-default.md +42 -0
- data/docs/dev/block-type-ux-echo-hash.md +6 -0
- data/docs/dev/block-type-ux-echo.md +3 -1
- data/docs/dev/block-type-ux-exec.md +1 -0
- data/docs/dev/block-type-ux-require.md +9 -18
- data/lib/fcb.rb +16 -4
- data/lib/hash_delegator.rb +139 -107
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/mdoc.rb +16 -14
- data/lib/menu.src.yml +12 -6
- data/lib/menu.yml +10 -5
- data/lib/namer.rb +1 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 718a29bb9eed1123158ffab68a01866fcdbc0126736c5305eae92dd661fb7396
|
4
|
+
data.tar.gz: 05e374bda6ac5603b13d50a33ef36cffd25d8fccdf43733107d63d19395ee9a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18629932f2c6b095329f56ec594eb1016df88b17278ef544f6954f793f054e55c137b8240692392ebba9165c15e0f58b6c1e3883447fa740c90fa1fccb20f351
|
7
|
+
data.tar.gz: bc1e0a9ea38227dc83136f2884934ed6dfed93a4c1e73c4c1faa8a6188b2bc7a197062d356f2e3ff5665629e04de46d40904191de9d23af9b6ba31c9f26953d5
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [2.8.5] - 2025-04-07
|
4
|
+
|
5
|
+
### Added
|
6
|
+
|
7
|
+
- Opts blocks can require other Opts blocks.
|
8
|
+
- Options to enable the change of shell expansion patterns.
|
9
|
+
- Default ID to each FCB.
|
10
|
+
- Convert the value of the 'echo' key to a string.
|
11
|
+
- All UX blocks are now loaded automatically.
|
12
|
+
|
13
|
+
### Changed
|
14
|
+
|
15
|
+
- Make 'default' key optional for UX blocks.
|
16
|
+
- Use the 'default' option to specify the initial computed value.
|
17
|
+
|
3
18
|
## [2.8.4] - 2025-03-24
|
4
19
|
|
5
20
|
### Added
|
data/Gemfile.lock
CHANGED
@@ -18,6 +18,7 @@ name: GENUS
|
|
18
18
|
allowed:
|
19
19
|
- Hominidae
|
20
20
|
- Antennariidae
|
21
|
+
default: ''
|
21
22
|
name: FAMILY
|
22
23
|
```
|
23
24
|
/ automatic block loads default value that is not in allowed list
|
@@ -40,6 +41,7 @@ name: CLASS
|
|
40
41
|
/ executed block presents a menu of the lines in the output of exec
|
41
42
|
```ux :[YEAR_DISCOVERED]
|
42
43
|
allowed: :exec
|
44
|
+
default: ''
|
43
45
|
exec: echo "2017\n2009"
|
44
46
|
name: YEAR_DISCOVERED
|
45
47
|
```
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/ v2025-02-08
|
2
|
+
/ name only
|
3
|
+
```ux
|
4
|
+
name: v1
|
5
|
+
```
|
6
|
+
/ name and default
|
7
|
+
/ transform and validate options not applied to default
|
8
|
+
```ux
|
9
|
+
default: 11
|
10
|
+
name: v2
|
11
|
+
```
|
12
|
+
/ name and default; auto-load
|
13
|
+
/ prompt option is ignored during auto-load
|
14
|
+
```ux :[document_ux_v3]
|
15
|
+
echo: 12
|
16
|
+
name: v3
|
17
|
+
```
|
18
|
+
/ name, default, exec; auto-load static
|
19
|
+
```ux :[document_ux_v4]
|
20
|
+
default: 21
|
21
|
+
exec: basename $(pwd)
|
22
|
+
name: v4
|
23
|
+
```
|
24
|
+
/ name, default, exec; auto-load executed `basename $(pwd)`
|
25
|
+
/ allowed is ignored by exec
|
26
|
+
```ux :[document_ux_v5]
|
27
|
+
exec: basename $(pwd)
|
28
|
+
name: v5
|
29
|
+
```
|
30
|
+
/ name, default, allowed; auto-load static default
|
31
|
+
```ux :[document_ux_v6]
|
32
|
+
allowed:
|
33
|
+
- 31
|
34
|
+
- 32
|
35
|
+
- 33
|
36
|
+
name: v6
|
37
|
+
```
|
38
|
+
@import bats-document-configuration.md
|
39
|
+
```opts :(document_opts)
|
40
|
+
menu_ux_row_format: '%{name} = ${%{name}}'
|
41
|
+
ux_auto_load_force_default: true
|
42
|
+
```
|
@@ -10,16 +10,19 @@ readonly: true
|
|
10
10
|
```
|
11
11
|
/ This block displays the second variable in the first block.
|
12
12
|
```ux :[DOCUMENTS]
|
13
|
+
default: false
|
13
14
|
name: DOCUMENTS
|
14
15
|
readonly: true
|
15
16
|
```
|
16
17
|
/ This block displays the third variable in the first block.
|
17
18
|
```ux :[OPERATION]
|
19
|
+
default: false
|
18
20
|
name: OPERATION
|
19
21
|
readonly: true
|
20
22
|
```
|
21
23
|
/ Multiple UX blocks to set many variables for a specific name.
|
22
24
|
```ux
|
25
|
+
default: false
|
23
26
|
echo:
|
24
27
|
Species: Pongo tapanuliensis
|
25
28
|
Genus: Pongo
|
@@ -34,6 +37,7 @@ menu_format: 'Load %{name}'
|
|
34
37
|
name: Tapanuli Orangutan
|
35
38
|
```
|
36
39
|
```ux
|
40
|
+
default: false
|
37
41
|
echo:
|
38
42
|
Species: Histiophryne psychedelica
|
39
43
|
Genus: Histiophryne
|
@@ -52,6 +56,7 @@ name: Psychedelic Frogfish
|
|
52
56
|
| -| -
|
53
57
|
/ A read-only variable in a UX block in a table
|
54
58
|
```ux
|
59
|
+
default: false
|
55
60
|
menu_format: '| %{name}| ${%{name}}'
|
56
61
|
name: Species
|
57
62
|
readonly: true
|
@@ -60,6 +65,7 @@ readonly: true
|
|
60
65
|
| Genus| ${Genus}
|
61
66
|
/ An editable variable in a UX block in a table
|
62
67
|
```ux
|
68
|
+
default: false
|
63
69
|
menu_format: '| %{name}| ${%{name}}'
|
64
70
|
name: Family
|
65
71
|
```
|
@@ -1,6 +1,5 @@
|
|
1
1
|
/ This automatic block sets VAR and displays the current value in the menu.
|
2
2
|
```ux :[document_ux_VAR]
|
3
|
-
default: :echo
|
4
3
|
echo: $(basename `pwd`)
|
5
4
|
name: VAR
|
6
5
|
```
|
@@ -10,11 +9,14 @@ menu_with_inherited_lines: true
|
|
10
9
|
```
|
11
10
|
/ This block is not visible. Execute to set a new value, displayed by the block above.
|
12
11
|
```ux :(VAR_has_count)
|
12
|
+
default: false
|
13
13
|
echo: $(basename `pwd` | wc -c)
|
14
|
+
force: false
|
14
15
|
name: VAR
|
15
16
|
```
|
16
17
|
/ This block is visible. Execute to set a new value, displayed by the block above.
|
17
18
|
```ux :[IAB_has_count]
|
19
|
+
default: false
|
18
20
|
echo: $VAR$VAR
|
19
21
|
name: IAB
|
20
22
|
```
|
@@ -1,32 +1,23 @@
|
|
1
|
-
/ an
|
1
|
+
/ This is an hidden shell block that is required by UX blocks.
|
2
2
|
``` :(shell)
|
3
3
|
ENTITY='Pongo tapanuliensis,Pongo'
|
4
4
|
```
|
5
|
-
```ux
|
6
|
-
|
7
|
-
exec: echo "${ENTITY%%,*}"
|
5
|
+
```ux +(shell)
|
6
|
+
echo: "${ENTITY%%,*}"
|
8
7
|
name: SPECIES
|
9
|
-
transform: :chomp
|
10
8
|
```
|
11
|
-
|
12
|
-
|
13
|
-
default: :exec
|
14
|
-
exec: echo "${ENTITY##*,}"
|
9
|
+
```ux +(shell)
|
10
|
+
echo: "${ENTITY##*,}"
|
15
11
|
name: GENUS
|
16
|
-
transform: :chomp
|
17
12
|
```
|
18
13
|
/ executed in context of prior ux blocks, uses their initial values
|
19
|
-
```ux
|
20
|
-
|
21
|
-
exec: echo "$SPECIES - $GENUS"
|
14
|
+
```ux
|
15
|
+
echo: "$SPECIES - $GENUS"
|
22
16
|
name: NAME
|
23
|
-
transform: :chomp
|
24
17
|
```
|
25
18
|
/ executed after other ux blocks, uses their initial values
|
26
|
-
```ux
|
27
|
-
|
28
|
-
exec: echo "$NAME"
|
19
|
+
```ux
|
20
|
+
echo: "$NAME"
|
29
21
|
name: NAME2
|
30
|
-
transform: :chomp
|
31
22
|
```
|
32
23
|
@import bats-document-configuration.md
|
data/lib/fcb.rb
CHANGED
@@ -48,6 +48,7 @@ module MarkdownExec
|
|
48
48
|
call: nil,
|
49
49
|
dname: nil,
|
50
50
|
headings: [],
|
51
|
+
id: object_id,
|
51
52
|
indent: '',
|
52
53
|
name: nil,
|
53
54
|
nickname: nil,
|
@@ -62,6 +63,15 @@ module MarkdownExec
|
|
62
63
|
}.merge(options)
|
63
64
|
end
|
64
65
|
|
66
|
+
def pub_name(**kwargs)
|
67
|
+
self.class.pub_name(@attrs, **kwargs)
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.pub_name(attrs, **kwargs)
|
71
|
+
full = attrs.fetch(:nickname, nil) || attrs.fetch(:oname, nil)
|
72
|
+
full&.to_s&.pub_name(**kwargs)
|
73
|
+
end
|
74
|
+
|
65
75
|
def code_name_included?(*names)
|
66
76
|
names.include?(@attrs[:oname])
|
67
77
|
end
|
@@ -331,13 +341,15 @@ if $PROGRAM_NAME == __FILE__
|
|
331
341
|
end
|
332
342
|
|
333
343
|
def test_to_h_method
|
334
|
-
assert_equal_hash @fcb_data.merge(
|
344
|
+
assert_equal_hash @fcb_data.merge(
|
345
|
+
{ id: @fcb.id, random: @fcb.random }
|
346
|
+
), @fcb.to_h
|
335
347
|
end
|
336
348
|
|
337
349
|
def test_to_yaml_method
|
338
|
-
assert_equal_hash YAML.load(@fcb_data.merge(
|
339
|
-
|
340
|
-
|
350
|
+
assert_equal_hash YAML.load(@fcb_data.merge(
|
351
|
+
{ id: @fcb.id, random: @fcb.random }
|
352
|
+
).to_yaml), YAML.load(@fcb.to_yaml)
|
341
353
|
end
|
342
354
|
|
343
355
|
def test_method_missing_getter
|
data/lib/hash_delegator.rb
CHANGED
@@ -1002,6 +1002,37 @@ module MarkdownExec
|
|
1002
1002
|
output.split("\n")
|
1003
1003
|
end
|
1004
1004
|
|
1005
|
+
def code_from_automatic_ux_blocks(
|
1006
|
+
all_blocks,
|
1007
|
+
mdoc
|
1008
|
+
)
|
1009
|
+
unless @ux_most_recent_filename != @delegate_object[:filename]
|
1010
|
+
return
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
blocks = select_automatic_ux_blocks(all_blocks)
|
1014
|
+
if blocks.empty?
|
1015
|
+
blocks = select_automatic_ux_blocks(all_blocks)
|
1016
|
+
end
|
1017
|
+
return if blocks.empty?
|
1018
|
+
|
1019
|
+
@ux_most_recent_filename = @delegate_object[:filename]
|
1020
|
+
|
1021
|
+
(blocks.each.with_object([]) do |block, merged_options|
|
1022
|
+
code = code_from_ux_block_to_set_environment_variables(
|
1023
|
+
block,
|
1024
|
+
mdoc,
|
1025
|
+
force: @delegate_object[:ux_auto_load_force_default],
|
1026
|
+
only_default: true
|
1027
|
+
)
|
1028
|
+
if code == :ux_exec_prohibited
|
1029
|
+
merged_options
|
1030
|
+
else
|
1031
|
+
merged_options.push(code)
|
1032
|
+
end
|
1033
|
+
end).to_a
|
1034
|
+
end
|
1035
|
+
|
1005
1036
|
# parse YAML body defining the UX for a single variable
|
1006
1037
|
# set ENV value for the variable and return code lines for the same
|
1007
1038
|
def code_from_ux_block_to_set_environment_variables(
|
@@ -1300,7 +1331,7 @@ module MarkdownExec
|
|
1300
1331
|
)
|
1301
1332
|
# Initialize a counter for named group occurrences
|
1302
1333
|
occurrence_count = Hash.new(0)
|
1303
|
-
return occurrence_count if pattern == //
|
1334
|
+
return occurrence_count if pattern.nil? || pattern == //
|
1304
1335
|
|
1305
1336
|
blocks.each do |block|
|
1306
1337
|
# Skip processing for shell-type blocks
|
@@ -1318,7 +1349,7 @@ module MarkdownExec
|
|
1318
1349
|
|
1319
1350
|
def count_named_group_occurrences_block_body_fix_indent(block)
|
1320
1351
|
### actually double the entries, but not a problem since it's used as a boolean
|
1321
|
-
([block.oname || ''] + block.body).join("\n")
|
1352
|
+
([block.oname || ''] + (block.body || [''])).join("\n")
|
1322
1353
|
end
|
1323
1354
|
|
1324
1355
|
##
|
@@ -1366,9 +1397,9 @@ module MarkdownExec
|
|
1366
1397
|
# split text with newlines, from variable expansion
|
1367
1398
|
if line_cap[:text].include?("\n")
|
1368
1399
|
lines = line_cap[:text].split("\n")
|
1369
|
-
line_caps =
|
1370
|
-
|
1371
|
-
|
1400
|
+
line_caps = lines.map do |line|
|
1401
|
+
line_cap.dup.merge(text: line)
|
1402
|
+
end.to_a
|
1372
1403
|
end
|
1373
1404
|
|
1374
1405
|
# wrap text on multiple lines to screen width, replacing line_caps
|
@@ -1376,7 +1407,7 @@ module MarkdownExec
|
|
1376
1407
|
line_caps = line_caps.flat_map do |line_cap|
|
1377
1408
|
text = line_cap[:text]
|
1378
1409
|
wrapper = StringWrapper.new(width: screen_width_for_wrapping - line_cap[:indent].length)
|
1379
|
-
|
1410
|
+
|
1380
1411
|
if text.length > screen_width_for_wrapping
|
1381
1412
|
# Wrap this text and create line_cap objects for each part
|
1382
1413
|
wrapper.wrap(text).map do |wrapped_text|
|
@@ -1486,7 +1517,9 @@ module MarkdownExec
|
|
1486
1517
|
yield if block_given?
|
1487
1518
|
|
1488
1519
|
# parse multiline to capture output of variable expansion
|
1489
|
-
mbody = fcb.body[0].match Regexp.new(
|
1520
|
+
mbody = fcb.body[0].match Regexp.new(
|
1521
|
+
@delegate_object[criteria[:match]], Regexp::MULTILINE
|
1522
|
+
)
|
1490
1523
|
end
|
1491
1524
|
|
1492
1525
|
create_and_add_chrome_block(
|
@@ -2406,14 +2439,16 @@ module MarkdownExec
|
|
2406
2439
|
expand_variable_references!(
|
2407
2440
|
blocks: [fcb],
|
2408
2441
|
initial_code_required: false,
|
2409
|
-
|
2442
|
+
key_format: @delegate_object[:variable_expression_format],
|
2443
|
+
link_state: link_state,
|
2444
|
+
pattern: options_variable_expression_regexp
|
2410
2445
|
)
|
2411
2446
|
expand_variable_references!(
|
2412
2447
|
blocks: [fcb],
|
2413
2448
|
echo_format: '%s',
|
2414
2449
|
group_name: :command,
|
2415
2450
|
initial_code_required: false,
|
2416
|
-
key_format:
|
2451
|
+
key_format: @delegate_object[:command_substitution_format],
|
2417
2452
|
link_state: link_state,
|
2418
2453
|
pattern: options_command_substitution_regexp
|
2419
2454
|
)
|
@@ -2424,13 +2459,10 @@ module MarkdownExec
|
|
2424
2459
|
echo_format: 'echo "$%s"',
|
2425
2460
|
group_name: :variable,
|
2426
2461
|
initial_code_required: false,
|
2427
|
-
key_format
|
2462
|
+
key_format:,
|
2428
2463
|
link_state:,
|
2429
|
-
pattern:
|
2464
|
+
pattern:
|
2430
2465
|
)
|
2431
|
-
pattern ||= options_variable_expression_regexp
|
2432
|
-
return if pattern.nil?
|
2433
|
-
|
2434
2466
|
variable_counts = count_named_group_occurrences(blocks, pattern,
|
2435
2467
|
group_name: group_name)
|
2436
2468
|
return if variable_counts.nil? || variable_counts == {}
|
@@ -2467,8 +2499,8 @@ module MarkdownExec
|
|
2467
2499
|
force:)
|
2468
2500
|
exportable = true
|
2469
2501
|
case export.echo
|
2470
|
-
when String
|
2471
|
-
value = export_echo_with_code_single(export.echo, inherited_code,
|
2502
|
+
when String, Integer, Float, TrueClass, FalseClass
|
2503
|
+
value = export_echo_with_code_single(export.echo.to_s, inherited_code,
|
2472
2504
|
code_lines, required)
|
2473
2505
|
when Hash
|
2474
2506
|
# each item in the hash is a variable name and value
|
@@ -2952,69 +2984,45 @@ module MarkdownExec
|
|
2952
2984
|
@fout.fout_list(list)
|
2953
2985
|
end
|
2954
2986
|
|
2955
|
-
# Loads auto blocks
|
2956
|
-
#
|
2957
|
-
#
|
2958
|
-
#
|
2959
|
-
#
|
2987
|
+
# Loads and updates auto options for document blocks if the current filename has changed.
|
2988
|
+
#
|
2989
|
+
# This method checks if the delegate object specifies a document load options block name and if the filename
|
2990
|
+
# has been updated. It then selects the appropriate blocks, collects their dependencies, processes their
|
2991
|
+
# options, and updates the menu base with the merged options.
|
2992
|
+
#
|
2993
|
+
# @param all_blocks [Array] An array of all block elements.
|
2994
|
+
# @param mdoc [Object] The document object managing dependencies and options.
|
2995
|
+
# @return [Boolean, nil] Returns true if options were updated; nil otherwise.
|
2960
2996
|
def load_auto_opts_block(all_blocks, mdoc:)
|
2961
|
-
|
2962
|
-
|
2963
|
-
@opts_most_recent_filename != @delegate_object[:filename]
|
2964
|
-
return
|
2965
|
-
end
|
2997
|
+
opts_block_name = @delegate_object[:document_load_opts_block_name]
|
2998
|
+
current_filename = @delegate_object[:filename]
|
2966
2999
|
|
2967
|
-
|
2968
|
-
|
3000
|
+
return unless opts_block_name.present? &&
|
3001
|
+
@opts_most_recent_filename != current_filename
|
3002
|
+
|
3003
|
+
selected_blocks = HashDelegator.block_select(all_blocks, :oname,
|
3004
|
+
opts_block_name)
|
3005
|
+
return if selected_blocks.empty?
|
3006
|
+
|
3007
|
+
dependency_map = {}
|
3008
|
+
selected_blocks.each do |block|
|
3009
|
+
mdoc.collect_dependencies(memo: dependency_map, block: block)
|
3010
|
+
end
|
2969
3011
|
|
2970
|
-
|
2971
|
-
|
3012
|
+
collected_options =
|
3013
|
+
dependency_map.each.with_object({}) do |(block_id, _), merged_options|
|
3014
|
+
matching_block = HashDelegator.block_find(all_blocks, :id, block_id)
|
2972
3015
|
options_state = read_show_options_and_trigger_reuse(
|
2973
|
-
mdoc: mdoc,
|
2974
|
-
selected: block
|
3016
|
+
mdoc: mdoc, selected: matching_block
|
2975
3017
|
)
|
2976
3018
|
merged_options.merge!(options_state.options)
|
2977
3019
|
end
|
2978
|
-
)
|
2979
3020
|
|
2980
|
-
|
3021
|
+
update_menu_base(collected_options)
|
3022
|
+
@opts_most_recent_filename = current_filename
|
2981
3023
|
true
|
2982
3024
|
end
|
2983
3025
|
|
2984
|
-
def load_auto_ux_block(
|
2985
|
-
all_blocks,
|
2986
|
-
mdoc,
|
2987
|
-
block_name: @delegate_object[:document_load_ux_block_name]
|
2988
|
-
)
|
2989
|
-
unless block_name.present? &&
|
2990
|
-
@ux_most_recent_filename != @delegate_object[:filename]
|
2991
|
-
return
|
2992
|
-
end
|
2993
|
-
|
2994
|
-
blocks = HashDelegator.block_select(all_blocks, :oname, block_name)
|
2995
|
-
if blocks.empty?
|
2996
|
-
blocks = HashDelegator.block_match(all_blocks, :nickname,
|
2997
|
-
Regexp.new(block_name))
|
2998
|
-
end
|
2999
|
-
return if blocks.empty?
|
3000
|
-
|
3001
|
-
@ux_most_recent_filename = @delegate_object[:filename]
|
3002
|
-
|
3003
|
-
(blocks.each.with_object([]) do |block, merged_options|
|
3004
|
-
code = code_from_ux_block_to_set_environment_variables(
|
3005
|
-
block,
|
3006
|
-
mdoc,
|
3007
|
-
force: @delegate_object[:ux_auto_load_force_default],
|
3008
|
-
only_default: true
|
3009
|
-
)
|
3010
|
-
if code == :ux_exec_prohibited
|
3011
|
-
merged_options
|
3012
|
-
else
|
3013
|
-
merged_options.push(code)
|
3014
|
-
end
|
3015
|
-
end).to_a
|
3016
|
-
end
|
3017
|
-
|
3018
3026
|
def load_auto_vars_block(
|
3019
3027
|
all_blocks,
|
3020
3028
|
block_name: @delegate_object[:document_load_vars_block_name]
|
@@ -3175,7 +3183,7 @@ module MarkdownExec
|
|
3175
3183
|
|
3176
3184
|
# load document ux block
|
3177
3185
|
#
|
3178
|
-
if (code_lines =
|
3186
|
+
if (code_lines = code_from_automatic_ux_blocks(all_blocks, mdoc))
|
3179
3187
|
new_code = HashDelegator.code_merge(link_state.inherited_lines,
|
3180
3188
|
code_lines)
|
3181
3189
|
next_state_set_code(nil, link_state, new_code)
|
@@ -3491,6 +3499,11 @@ module MarkdownExec
|
|
3491
3499
|
fout_execution_report if @delegate_object[:output_execution_report]
|
3492
3500
|
end
|
3493
3501
|
|
3502
|
+
# all UX blocks are automatic for the document
|
3503
|
+
def select_automatic_ux_blocks(blocks)
|
3504
|
+
blocks.select { |item| item.type == 'ux' }
|
3505
|
+
end
|
3506
|
+
|
3494
3507
|
# Filter blocks per block_name_include_match, block_name_wrapper_match.
|
3495
3508
|
#
|
3496
3509
|
# @param all_blocks [Array<Hash>] The list of blocks from the file.
|
@@ -4481,56 +4494,75 @@ module MarkdownExec
|
|
4481
4494
|
def ux_block_export_automatic(export, inherited_code, code_lines, required)
|
4482
4495
|
transformable = true
|
4483
4496
|
exportable = true
|
4484
|
-
[case export.default
|
4485
|
-
when :allowed
|
4486
|
-
raise unless export.allowed.present?
|
4487
4497
|
|
4488
|
-
|
4489
|
-
|
4490
|
-
|
4491
|
-
|
4492
|
-
|
4498
|
+
if export.default == false
|
4499
|
+
exportable = false
|
4500
|
+
transformable = false
|
4501
|
+
value = nil
|
4502
|
+
else
|
4503
|
+
if export.default.nil?
|
4504
|
+
if export.echo.present?
|
4505
|
+
export.default = :echo
|
4506
|
+
elsif export.exec.present?
|
4507
|
+
export.default = :exec
|
4508
|
+
elsif export.allowed.present?
|
4509
|
+
export.default = export.allowed.first
|
4510
|
+
end
|
4511
|
+
end
|
4493
4512
|
|
4494
|
-
|
4513
|
+
value = case export.default
|
4514
|
+
when :allowed
|
4515
|
+
raise unless export.allowed.present?
|
4495
4516
|
|
4496
|
-
|
4497
|
-
|
4498
|
-
|
4499
|
-
|
4517
|
+
if export.allowed == :echo
|
4518
|
+
output, exportable = export_echo_with_code(
|
4519
|
+
export, inherited_code, code_lines, required, force: false
|
4520
|
+
)
|
4521
|
+
return :ux_exec_prohibited if output == :invalidated
|
4500
4522
|
|
4501
|
-
|
4523
|
+
exportable && output.split("\n").first
|
4502
4524
|
|
4503
|
-
|
4504
|
-
|
4505
|
-
|
4525
|
+
elsif export.allowed == :exec
|
4526
|
+
output = process_allowed_exec(export, inherited_code,
|
4527
|
+
code_lines, required)
|
4528
|
+
return :ux_exec_prohibited if output == :ux_exec_prohibited
|
4506
4529
|
|
4507
|
-
|
4508
|
-
when :echo
|
4509
|
-
raise unless export.echo.present?
|
4530
|
+
output.first
|
4510
4531
|
|
4511
|
-
|
4512
|
-
|
4513
|
-
|
4514
|
-
return :ux_exec_prohibited if output == :invalidated
|
4532
|
+
else
|
4533
|
+
export.allowed.first
|
4534
|
+
end
|
4515
4535
|
|
4516
|
-
|
4536
|
+
# echo > default
|
4537
|
+
when :echo
|
4538
|
+
raise unless export.echo.present?
|
4517
4539
|
|
4518
|
-
|
4519
|
-
|
4520
|
-
|
4540
|
+
output, exportable = export_echo_with_code(
|
4541
|
+
export, inherited_code, code_lines, required, force: false
|
4542
|
+
)
|
4543
|
+
return :ux_exec_prohibited if output == :invalidated
|
4521
4544
|
|
4522
|
-
|
4523
|
-
export, inherited_code, code_lines, required
|
4524
|
-
)
|
4525
|
-
return :ux_exec_prohibited if output == :invalidated
|
4545
|
+
output
|
4526
4546
|
|
4527
|
-
|
4547
|
+
# exec > default
|
4548
|
+
when :exec
|
4549
|
+
raise unless export.exec.present?
|
4528
4550
|
|
4529
|
-
|
4530
|
-
|
4531
|
-
|
4532
|
-
|
4533
|
-
|
4551
|
+
output = export_exec_with_code(
|
4552
|
+
export, inherited_code, code_lines, required
|
4553
|
+
)
|
4554
|
+
return :ux_exec_prohibited if output == :invalidated
|
4555
|
+
|
4556
|
+
output
|
4557
|
+
|
4558
|
+
# default
|
4559
|
+
else
|
4560
|
+
transformable = false
|
4561
|
+
export.default.to_s
|
4562
|
+
end
|
4563
|
+
end
|
4564
|
+
|
4565
|
+
[value,
|
4534
4566
|
exportable,
|
4535
4567
|
transformable]
|
4536
4568
|
end
|
data/lib/mdoc.rb
CHANGED
@@ -83,7 +83,7 @@ module MarkdownExec
|
|
83
83
|
|
84
84
|
nickname = name_block.pub_name
|
85
85
|
|
86
|
-
dependencies = collect_dependencies(nickname)
|
86
|
+
dependencies = collect_dependencies(source: nickname)
|
87
87
|
# !!t dependencies.count
|
88
88
|
all_dependency_names =
|
89
89
|
collect_unique_names(dependencies).push(nickname).uniq
|
@@ -405,21 +405,23 @@ module MarkdownExec
|
|
405
405
|
# @param source [String] The name of the initial source block.
|
406
406
|
# @param memo [Hash] A memoization hash to store resolved dependencies.
|
407
407
|
# @return [Hash] A hash mapping sources to their respective dependencies.
|
408
|
-
def collect_dependencies(
|
409
|
-
|
408
|
+
def collect_dependencies(block: nil, memo: {}, source: nil)
|
409
|
+
if block.nil?
|
410
|
+
return memo unless source
|
410
411
|
|
411
|
-
|
412
|
-
|
413
|
-
|
412
|
+
block = get_block_by_anyname(source)
|
413
|
+
if block.nil? || block.instance_of?(Hash)
|
414
|
+
raise "Named code block `#{source}` not found. (@#{__LINE__})"
|
415
|
+
end
|
414
416
|
end
|
415
|
-
|
416
417
|
return memo unless block.reqs
|
417
418
|
|
418
|
-
memo[
|
419
|
+
memo[block.id] = block.reqs
|
419
420
|
|
420
421
|
block.reqs.each do |req|
|
421
|
-
collect_dependencies(req, memo) unless memo.key?(req)
|
422
|
+
collect_dependencies(source: req, memo: memo) unless memo.key?(req)
|
422
423
|
end
|
424
|
+
|
423
425
|
memo
|
424
426
|
end
|
425
427
|
|
@@ -463,24 +465,24 @@ if $PROGRAM_NAME == __FILE__
|
|
463
465
|
end
|
464
466
|
|
465
467
|
def test_collect_dependencies_with_no_source
|
466
|
-
assert_empty @mdoc.collect_dependencies
|
468
|
+
assert_empty @mdoc.collect_dependencies
|
467
469
|
end
|
468
470
|
|
469
471
|
### must raise error
|
470
472
|
def test_collect_dependencies_with_nonexistent_source
|
471
473
|
assert_raises(RuntimeError) do
|
472
|
-
@mdoc.collect_dependencies('nonexistent')
|
474
|
+
@mdoc.collect_dependencies(source: 'nonexistent')
|
473
475
|
end
|
474
476
|
end if false
|
475
477
|
|
476
478
|
def test_collect_dependencies_with_valid_source
|
477
479
|
@mdoc.stubs(:get_block_by_anyname)
|
478
|
-
.with('source1').returns(OpenStruct.new(reqs: ['source2']))
|
480
|
+
.with('source1').returns(OpenStruct.new(id: 'source1', reqs: ['source2']))
|
479
481
|
@mdoc.stubs(:get_block_by_anyname)
|
480
|
-
.with('source2').returns(OpenStruct.new(reqs: []))
|
482
|
+
.with('source2').returns(OpenStruct.new(id: 'source2', reqs: []))
|
481
483
|
|
482
484
|
expected = { 'source1' => ['source2'], 'source2' => [] }
|
483
|
-
assert_equal expected, @mdoc.collect_dependencies('source1')
|
485
|
+
assert_equal expected, @mdoc.collect_dependencies(source: 'source1')
|
484
486
|
end
|
485
487
|
end
|
486
488
|
|
data/lib/menu.src.yml
CHANGED
@@ -103,6 +103,12 @@
|
|
103
103
|
:default: true
|
104
104
|
:procname: val_as_bool
|
105
105
|
|
106
|
+
- :opt_name: command_substitution_format
|
107
|
+
:env_var: MDE_COMMAND_SUBSTITUTION_FORMAT
|
108
|
+
:description: command_substitution_format
|
109
|
+
:default: '$(%s)'
|
110
|
+
:procname: val_as_str
|
111
|
+
|
106
112
|
- :opt_name: command_substitution_regexp
|
107
113
|
:env_var: MDE_COMMAND_SUBSTITUTION_REGEXP
|
108
114
|
:description: command_substitution_regexp
|
@@ -207,12 +213,6 @@
|
|
207
213
|
:default: "(document_shell)"
|
208
214
|
:procname: val_as_str
|
209
215
|
|
210
|
-
- :opt_name: document_load_ux_block_name
|
211
|
-
:env_var: MDE_DOCUMENT_LOAD_UX_BLOCK_NAME
|
212
|
-
:description: Name of UX block to load with the document
|
213
|
-
:default: "\\[.*document_ux.*\\]"
|
214
|
-
:procname: val_as_str
|
215
|
-
|
216
216
|
- :opt_name: document_load_vars_block_name
|
217
217
|
:env_var: MDE_DOCUMENT_LOAD_VARS_BLOCK_NAME
|
218
218
|
:description: Name of Vars block to load with the document
|
@@ -1663,6 +1663,12 @@
|
|
1663
1663
|
:default: true
|
1664
1664
|
:procname: val_as_bool
|
1665
1665
|
|
1666
|
+
- :opt_name: variable_expression_format
|
1667
|
+
:env_var: MDE_VARIABLE_EXPRESSION_FORMAT
|
1668
|
+
:description: variable_expression_format
|
1669
|
+
:default: '${%s}'
|
1670
|
+
:procname: val_as_str
|
1671
|
+
|
1666
1672
|
- :opt_name: variable_expression_regexp
|
1667
1673
|
:env_var: MDE_VARIABLE_EXPRESSION_REGEXP
|
1668
1674
|
:description: variable_expression_regexp
|
data/lib/menu.yml
CHANGED
@@ -84,6 +84,11 @@
|
|
84
84
|
:arg_name: BOOL
|
85
85
|
:default: true
|
86
86
|
:procname: val_as_bool
|
87
|
+
- :opt_name: command_substitution_format
|
88
|
+
:env_var: MDE_COMMAND_SUBSTITUTION_FORMAT
|
89
|
+
:description: command_substitution_format
|
90
|
+
:default: "$(%s)"
|
91
|
+
:procname: val_as_str
|
87
92
|
- :opt_name: command_substitution_regexp
|
88
93
|
:env_var: MDE_COMMAND_SUBSTITUTION_REGEXP
|
89
94
|
:description: command_substitution_regexp
|
@@ -172,11 +177,6 @@
|
|
172
177
|
:description: Name of shell block to load with the document
|
173
178
|
:default: "(document_shell)"
|
174
179
|
:procname: val_as_str
|
175
|
-
- :opt_name: document_load_ux_block_name
|
176
|
-
:env_var: MDE_DOCUMENT_LOAD_UX_BLOCK_NAME
|
177
|
-
:description: Name of UX block to load with the document
|
178
|
-
:default: "\\[.*document_ux.*\\]"
|
179
|
-
:procname: val_as_str
|
180
180
|
- :opt_name: document_load_vars_block_name
|
181
181
|
:env_var: MDE_DOCUMENT_LOAD_VARS_BLOCK_NAME
|
182
182
|
:description: Name of Vars block to load with the document
|
@@ -1419,6 +1419,11 @@
|
|
1419
1419
|
:arg_name: BOOL
|
1420
1420
|
:default: true
|
1421
1421
|
:procname: val_as_bool
|
1422
|
+
- :opt_name: variable_expression_format
|
1423
|
+
:env_var: MDE_VARIABLE_EXPRESSION_FORMAT
|
1424
|
+
:description: variable_expression_format
|
1425
|
+
:default: "${%s}"
|
1426
|
+
:procname: val_as_str
|
1422
1427
|
- :opt_name: variable_expression_regexp
|
1423
1428
|
:env_var: MDE_VARIABLE_EXPRESSION_REGEXP
|
1424
1429
|
:description: variable_expression_regexp
|
data/lib/namer.rb
CHANGED
@@ -9,9 +9,7 @@ class Hash
|
|
9
9
|
# block name in commands and documents
|
10
10
|
def pub_name(**kwargs)
|
11
11
|
full = fetch(:nickname, nil) || fetch(:oname, nil)
|
12
|
-
full&.to_s&.pub_name(**kwargs)
|
13
|
-
pp [__LINE__, 'Hash.pub_name() ->', ret] if $pd
|
14
|
-
end
|
12
|
+
full&.to_s&.pub_name(**kwargs)
|
15
13
|
end
|
16
14
|
end
|
17
15
|
|
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.5
|
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-04-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- bats/block-type-ux-allowed.bats
|
116
116
|
- bats/block-type-ux-auto.bats
|
117
117
|
- bats/block-type-ux-chained.bats
|
118
|
+
- bats/block-type-ux-default.bats
|
118
119
|
- bats/block-type-ux-echo-hash.bats
|
119
120
|
- bats/block-type-ux-echo.bats
|
120
121
|
- bats/block-type-ux-exec.bats
|
@@ -163,6 +164,7 @@ files:
|
|
163
164
|
- docs/dev/block-type-ux-allowed.md
|
164
165
|
- docs/dev/block-type-ux-auto.md
|
165
166
|
- docs/dev/block-type-ux-chained.md
|
167
|
+
- docs/dev/block-type-ux-default.md
|
166
168
|
- docs/dev/block-type-ux-echo-hash.md
|
167
169
|
- docs/dev/block-type-ux-echo.md
|
168
170
|
- docs/dev/block-type-ux-exec.md
|