markdown_exec 2.8.0 → 2.8.1
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/Gemfile.lock +1 -1
- data/bats/block-type-ux-auto.bats +8 -0
- data/bats/block-type-ux-exec.bats +8 -0
- data/bats/block-type-ux-row-format.bats +8 -0
- data/bats/block-type-ux-transform.bats +8 -0
- data/bin/tab_completion.sh +1 -1
- data/docs/dev/block-type-ux-auto.md +43 -0
- data/docs/dev/block-type-ux-exec.md +42 -0
- data/docs/dev/block-type-ux-row-format.md +47 -0
- data/docs/dev/block-type-ux-transform.md +41 -0
- data/lib/constants.rb +2 -0
- data/lib/fcb.rb +0 -32
- data/lib/hash_delegator.rb +115 -53
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/mdoc.rb +51 -21
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d752af0db5e1c1a770b64f9341c3d08e1e9bc8612230a9cb44ddc7fddc4c3051
|
4
|
+
data.tar.gz: 5ba8524b3323bd8333b82a5d0607fbb9db59a5157a1c7ae0564b3f624f26addd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29b210e56b46a1edf099c02267e2b3c7cdae6701f7ee99d5a946d06eea7272da3534765110ec36a6de017a10d0f4833c9075c27dacb0cec8b050192d3892d748
|
7
|
+
data.tar.gz: e73cd906ce9035c8c78d2e301866af4a76bc7a730c5109fc8cc59ecf64679cb578fb04b324e700df064886d250c394c441f77850b9e21230d346d08bd92a9a5f
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
load 'test_helper'
|
4
|
+
|
5
|
+
@test 'Row format merges with prior table' {
|
6
|
+
spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-row-format.md \
|
7
|
+
' | Variable | Value | Prompt |_ | --------- | ---------------- | ------------------- |_ | Species | Pongo tapanulien | New species? |_ | Name: Gen | Value: Pongo | Prompt: New genus? |_ | Family | Hominidae | Enter a value: |'
|
8
|
+
}
|
@@ -0,0 +1,8 @@
|
|
1
|
+
#!/usr/bin/env bats
|
2
|
+
|
3
|
+
load 'test_helper'
|
4
|
+
|
5
|
+
@test 'Transformed output of executed commands' {
|
6
|
+
spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-transform.md \
|
7
|
+
'_Execution output has a trailing newline._Var0=markdown_exec_00000000 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 0a |markdown_exec.|__With validate and transform, output has no newline._Var1=markdown_exec_00000000 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 |markdown_exec|__With transform :chomp, output has no newline._Var2=markdown_exec_00000000 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 |markdown_exec|__With transform :upcase, output is in upper case w/ newline._Var3=MARKDOWN_EXEC_00000000 4d 41 52 4b 44 4f 57 4e 5f 45 58 45 43 0a |MARKDOWN_EXEC.|'
|
8
|
+
}
|
data/bin/tab_completion.sh
CHANGED
@@ -0,0 +1,43 @@
|
|
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
|
+
default: 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
|
+
default: :exec
|
28
|
+
exec: basename $(pwd)
|
29
|
+
name: v5
|
30
|
+
```
|
31
|
+
/ name, default, allowed; auto-load static default
|
32
|
+
```ux :[document_ux_v6]
|
33
|
+
allowed:
|
34
|
+
- 32
|
35
|
+
- 33
|
36
|
+
default: 31
|
37
|
+
name: v6
|
38
|
+
```
|
39
|
+
@import bats-document-configuration.md
|
40
|
+
```opts :(document_opts)
|
41
|
+
menu_ux_row_format: '%{name} = ${%{name}}'
|
42
|
+
ux_auto_load_force_default: true
|
43
|
+
```
|
@@ -0,0 +1,42 @@
|
|
1
|
+
/ auto-load block, does not execute command to calculate
|
2
|
+
/ click block to calculate
|
3
|
+
```ux :[document_ux0]
|
4
|
+
exec: basename $(pwd)
|
5
|
+
name: ux0
|
6
|
+
```
|
7
|
+
/ auto-load block and execute command to calculate
|
8
|
+
/ click block to recalculate
|
9
|
+
```ux :[document_ux1]
|
10
|
+
default: Unknown
|
11
|
+
exec: basename $(pwd)
|
12
|
+
name: ux1
|
13
|
+
```
|
14
|
+
/ auto-load block and execute command to calculate
|
15
|
+
/ click block to recalculate
|
16
|
+
```ux :[document_ux2]
|
17
|
+
default: :exec
|
18
|
+
exec: basename $(pwd)
|
19
|
+
name: ux2
|
20
|
+
```
|
21
|
+
/ required block defining a function used in exec
|
22
|
+
```bash :(bash3)
|
23
|
+
# function from bash3
|
24
|
+
val () { basename $(pwd) ; }
|
25
|
+
```
|
26
|
+
```ux :[document_ux3] +(bash3)
|
27
|
+
default: :exec
|
28
|
+
exec: val
|
29
|
+
name: ux3
|
30
|
+
```
|
31
|
+
/ default is computed
|
32
|
+
/ output of execution is validated/parsed
|
33
|
+
/ parsing is transformed
|
34
|
+
```ux :[document_ux4]
|
35
|
+
default: :exec
|
36
|
+
exec: basename $(pwd)
|
37
|
+
name: ux4
|
38
|
+
transform: "Xform: '%{name}'"
|
39
|
+
validate: |
|
40
|
+
^(?<name>.*)(_.*)$
|
41
|
+
```
|
42
|
+
@import bats-document-configuration.md
|
@@ -0,0 +1,47 @@
|
|
1
|
+
/ v2025-02-08
|
2
|
+
| Variable| Value| Prompt
|
3
|
+
| -| -| -
|
4
|
+
/ auto-load default value
|
5
|
+
/ custom prompt
|
6
|
+
/ select list
|
7
|
+
/ default value
|
8
|
+
```ux :[document_ux_Species]
|
9
|
+
allowed:
|
10
|
+
- Pongo tapanuliensis
|
11
|
+
- Histiophryne psychedelica
|
12
|
+
- Phyllopteryx dewysea
|
13
|
+
default: Pongo tapanuliensis
|
14
|
+
name: Species
|
15
|
+
prompt: New species?
|
16
|
+
```
|
17
|
+
/ auto-load default value
|
18
|
+
/ cell text is prefixed Name/Value/Prompt
|
19
|
+
/ select list contains additional text
|
20
|
+
/ selected value is validated with named groups
|
21
|
+
/ selected value is transformed; named capture is prefixed Xform
|
22
|
+
```ux :[document_ux_Genus]
|
23
|
+
allowed:
|
24
|
+
- 1. Pongo
|
25
|
+
- 2. Histiophryne
|
26
|
+
- 3. Phyllopteryx
|
27
|
+
default: Pongo
|
28
|
+
menu_format: "| Name: %{name}| Value: ${%{name}}| Prompt: %{prompt}"
|
29
|
+
name: Genus
|
30
|
+
prompt: New genus?
|
31
|
+
transform: "Xform: '%{name}'"
|
32
|
+
validate: |
|
33
|
+
^\d+\. *(?<name>[^ ].*)$
|
34
|
+
```
|
35
|
+
/ default
|
36
|
+
/ auto-load default value
|
37
|
+
```ux :[document_ux_Family]
|
38
|
+
default: Hominidae
|
39
|
+
name: Family
|
40
|
+
```
|
41
|
+
@import bats-document-configuration.md
|
42
|
+
```opts :(document_opts)
|
43
|
+
menu_ux_row_format: '| %{name}| ${%{name}}| %{prompt}'
|
44
|
+
screen_width: 64
|
45
|
+
table_center: true
|
46
|
+
ux_auto_load_force_default: true
|
47
|
+
```
|
@@ -0,0 +1,41 @@
|
|
1
|
+
:::
|
2
|
+
**Execution output has a trailing newline.**
|
3
|
+
```ux :[document_ux_transform_0]
|
4
|
+
default: :exec
|
5
|
+
exec: basename $(pwd)
|
6
|
+
name: Var0
|
7
|
+
```
|
8
|
+
$(echo -n "$Var0" | hexdump -C)
|
9
|
+
:::
|
10
|
+
**With validate and transform, output has no newline.**
|
11
|
+
```ux :[document_ux_transform_1]
|
12
|
+
default: :exec
|
13
|
+
exec: basename $(pwd)
|
14
|
+
name: Var1
|
15
|
+
transform: '%{name}'
|
16
|
+
validate: (?<name>.+)
|
17
|
+
```
|
18
|
+
$(echo -n "$Var1" | hexdump -C)
|
19
|
+
:::
|
20
|
+
**With transform `:chomp`, output has no newline.**
|
21
|
+
```ux :[document_ux_transform_2]
|
22
|
+
default: :exec
|
23
|
+
exec: basename $(pwd)
|
24
|
+
name: Var2
|
25
|
+
transform: :chomp
|
26
|
+
```
|
27
|
+
$(echo -n "$Var2" | hexdump -C)
|
28
|
+
:::
|
29
|
+
**With transform `:upcase`, output is in upper case w/ newline.**
|
30
|
+
```ux :[document_ux_transform_3]
|
31
|
+
default: :exec
|
32
|
+
exec: basename $(pwd)
|
33
|
+
name: Var3
|
34
|
+
transform: :upcase
|
35
|
+
```
|
36
|
+
$(echo -n "$Var3" | hexdump -C)
|
37
|
+
@import bats-document-configuration.md
|
38
|
+
```opts :(document_opts)
|
39
|
+
divider4_collapsible: false
|
40
|
+
table_center: false
|
41
|
+
```
|
data/lib/constants.rb
CHANGED
data/lib/fcb.rb
CHANGED
@@ -56,10 +56,6 @@ module MarkdownExec
|
|
56
56
|
title: '',
|
57
57
|
type: ''
|
58
58
|
}.merge(options)
|
59
|
-
# @attrs[:raw_body] ||= @attrs[:body]
|
60
|
-
# @attrs[:raw_dname] ||= @attrs[:dname]
|
61
|
-
# @attrs[:raw_s0printable] ||= @attrs[:s0printable]
|
62
|
-
# @attrs[:raw_s1decorated] ||= @attrs[:s1decorated]
|
63
59
|
end
|
64
60
|
|
65
61
|
def code_name_included?(*names)
|
@@ -92,34 +88,6 @@ module MarkdownExec
|
|
92
88
|
end
|
93
89
|
end
|
94
90
|
|
95
|
-
# def body=(value)
|
96
|
-
# ww0 'body=', value
|
97
|
-
# # binding.irb
|
98
|
-
# @attrs[:raw_body] ||= value
|
99
|
-
# @attrs[:body] = value
|
100
|
-
# end
|
101
|
-
|
102
|
-
# def dname=(value)
|
103
|
-
# ww0 'dname=', value
|
104
|
-
# binding.irb if value == ' | Species| Not specified'
|
105
|
-
# @attrs[:raw_dname] ||= value
|
106
|
-
# @attrs[:dname] = value
|
107
|
-
# end
|
108
|
-
|
109
|
-
# def s0printable=(value)
|
110
|
-
# ww0 's0printable=', value
|
111
|
-
# # binding.irb
|
112
|
-
# @attrs[:raw_s0printable] ||= value
|
113
|
-
# @attrs[:s0printable] = value
|
114
|
-
# end
|
115
|
-
|
116
|
-
# def s1decorated=(value)
|
117
|
-
# ww0 's1decorated=', value
|
118
|
-
# # binding.irb
|
119
|
-
# @attrs[:raw_s1decorated] ||= value
|
120
|
-
# @attrs[:s1decorated] = value
|
121
|
-
# end
|
122
|
-
|
123
91
|
# Processes a block to generate its summary, modifying its attributes
|
124
92
|
# based on various matching criteria.
|
125
93
|
# It handles special formatting for bash blocks, extracting and setting
|
data/lib/hash_delegator.rb
CHANGED
@@ -934,7 +934,12 @@ module MarkdownExec
|
|
934
934
|
end
|
935
935
|
end
|
936
936
|
|
937
|
-
|
937
|
+
def build_menu_options(exit_option, display_mode_option,
|
938
|
+
menu_entries, display_format)
|
939
|
+
[exit_option,
|
940
|
+
display_mode_option,
|
941
|
+
*menu_entries.map(&display_format)].compact
|
942
|
+
end
|
938
943
|
|
939
944
|
def build_replacement_dictionary(
|
940
945
|
commands, link_state,
|
@@ -1061,7 +1066,8 @@ module MarkdownExec
|
|
1061
1066
|
when :exec
|
1062
1067
|
raise unless export.exec.present?
|
1063
1068
|
|
1064
|
-
n1 = neval(export.exec,
|
1069
|
+
n1 = neval(export.exec,
|
1070
|
+
(inherited_code || []) + required[:code])
|
1065
1071
|
|
1066
1072
|
if export.transform.present?
|
1067
1073
|
if export.transform.is_a? Symbol
|
@@ -1167,7 +1173,6 @@ module MarkdownExec
|
|
1167
1173
|
|
1168
1174
|
def code_line_safe_assign(name, value, force:)
|
1169
1175
|
if force
|
1170
|
-
# ww0 value
|
1171
1176
|
"#{name}=#{Shellwords.escape(value)}"
|
1172
1177
|
else
|
1173
1178
|
"[[ -z $#{name} ]] && #{name}=#{Shellwords.escape(value)}"
|
@@ -1981,19 +1986,23 @@ module MarkdownExec
|
|
1981
1986
|
block_source: block_source
|
1982
1987
|
)
|
1983
1988
|
|
1984
|
-
#
|
1985
|
-
|
1986
|
-
|
1987
|
-
|
1988
|
-
|
1989
|
-
|
1989
|
+
# 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)
|
1993
|
+
block_selection = BlockSelection.new(selected.id)
|
1994
|
+
end
|
1995
|
+
|
1996
|
+
{ link_state: lfls.link_state,
|
1997
|
+
block_selection: block_selection,
|
1998
|
+
quit: lfls.load_file == LoadFile::EXIT }
|
1990
1999
|
end
|
1991
2000
|
|
1992
2001
|
def execute_block_in_state(block_name)
|
1993
2002
|
@dml_block_state = block_state_for_name_from_cli(block_name)
|
1994
2003
|
dump_and_warn_block_state(name: block_name,
|
1995
2004
|
selected: @dml_block_state.block)
|
1996
|
-
|
2005
|
+
next_block_state =
|
1997
2006
|
execute_block_for_state_and_name(
|
1998
2007
|
selected: @dml_block_state.block,
|
1999
2008
|
mdoc: @dml_mdoc,
|
@@ -2005,7 +2014,10 @@ module MarkdownExec
|
|
2005
2014
|
)
|
2006
2015
|
}
|
2007
2016
|
)
|
2008
|
-
|
2017
|
+
|
2018
|
+
@dml_link_state = next_block_state[:link_state]
|
2019
|
+
@dml_block_selection = next_block_state[:block_selection]
|
2020
|
+
:break if next_block_state[:quit]
|
2009
2021
|
end
|
2010
2022
|
|
2011
2023
|
def execute_block_type_history_ux(
|
@@ -2152,6 +2164,7 @@ module MarkdownExec
|
|
2152
2164
|
block_data['glob'] || glob
|
2153
2165
|
)
|
2154
2166
|
)
|
2167
|
+
dirs.sort_by! { |f| File.mtime(f) }.reverse!
|
2155
2168
|
|
2156
2169
|
if !contains_glob?(block_data['directory']) &&
|
2157
2170
|
!contains_glob?(block_data['glob'])
|
@@ -2162,7 +2175,7 @@ module MarkdownExec
|
|
2162
2175
|
end
|
2163
2176
|
elsif selected_option = select_option_with_metadata(
|
2164
2177
|
prompt_title,
|
2165
|
-
[exit_prompt] + dirs.
|
2178
|
+
[exit_prompt] + dirs.map do |file|
|
2166
2179
|
{ name: format(
|
2167
2180
|
block_data['view'] || view,
|
2168
2181
|
NamedCaptureExtractor.extract_named_group_match_data(
|
@@ -2326,41 +2339,25 @@ module MarkdownExec
|
|
2326
2339
|
)
|
2327
2340
|
# repeat select+display until user exits
|
2328
2341
|
|
2329
|
-
|
2330
|
-
|
2331
|
-
|
2332
|
-
|
2333
|
-
|
2334
|
-
|
2335
|
-
|
2336
|
-
|
2337
|
-
|
2338
|
-
|
2339
|
-
|
2340
|
-
|
2341
|
-
|
2342
|
-
|
2343
|
-
|
2344
|
-
|
2345
|
-
|
2346
|
-
|
2347
|
-
|
2348
|
-
pause_now = false
|
2349
|
-
else
|
2350
|
-
file = files_table_rows.select { |ftr| ftr.row == name }&.first
|
2351
|
-
info = file_info(file.file)
|
2352
|
-
stream.puts "#{file.file} - #{info[:lines]} lines / " \
|
2353
|
-
"#{info[:size]} bytes"
|
2354
|
-
stream.puts(
|
2355
|
-
File.readlines(file.file,
|
2356
|
-
chomp: false).map.with_index do |line, ind|
|
2357
|
-
format(' %s. %s',
|
2358
|
-
AnsiString.new(format('% 4d', ind + 1)).send(:violet),
|
2359
|
-
line)
|
2360
|
-
end
|
2361
|
-
)
|
2362
|
-
pause_now = pause_refresh
|
2363
|
-
end
|
2342
|
+
interactive_menu_with_display_modes(
|
2343
|
+
files_table_rows,
|
2344
|
+
display_formats: [:row, :file],
|
2345
|
+
display_mode_option: @delegate_object[:prompt_filespec_facet],
|
2346
|
+
exit_option: exit_prompt,
|
2347
|
+
menu_title: @delegate_object[:prompt_select_history_file],
|
2348
|
+
pause_after_selection: pause_refresh
|
2349
|
+
) do |file|
|
2350
|
+
info = file_info(file.file)
|
2351
|
+
stream.puts "#{file.file} - #{info[:lines]} lines / " \
|
2352
|
+
"#{info[:size]} bytes"
|
2353
|
+
stream.puts(
|
2354
|
+
File.readlines(file.file,
|
2355
|
+
chomp: false).map.with_index do |line, ind|
|
2356
|
+
format(' %s. %s',
|
2357
|
+
AnsiString.new(format('% 4d', ind + 1)).send(:violet),
|
2358
|
+
line)
|
2359
|
+
end
|
2360
|
+
)
|
2364
2361
|
end
|
2365
2362
|
end
|
2366
2363
|
|
@@ -2679,6 +2676,56 @@ module MarkdownExec
|
|
2679
2676
|
}
|
2680
2677
|
end
|
2681
2678
|
|
2679
|
+
def interactive_menu_with_display_modes(
|
2680
|
+
menu_entries,
|
2681
|
+
display_formats:,
|
2682
|
+
display_mode_option:,
|
2683
|
+
exit_option:,
|
2684
|
+
menu_title:,
|
2685
|
+
pause_after_selection:
|
2686
|
+
)
|
2687
|
+
pause_menu = false
|
2688
|
+
current_display_format = display_formats.first
|
2689
|
+
|
2690
|
+
loop do
|
2691
|
+
break if pause_menu && (prompt_select_continue == MenuState::EXIT)
|
2692
|
+
|
2693
|
+
menu_options = build_menu_options(
|
2694
|
+
exit_option, display_mode_option,
|
2695
|
+
menu_entries, current_display_format
|
2696
|
+
)
|
2697
|
+
|
2698
|
+
selection = prompt_select_code_filename(
|
2699
|
+
menu_options,
|
2700
|
+
string: menu_title,
|
2701
|
+
color_sym: :prompt_color_after_script_execution
|
2702
|
+
)
|
2703
|
+
|
2704
|
+
case selection
|
2705
|
+
when exit_option
|
2706
|
+
break
|
2707
|
+
when display_mode_option
|
2708
|
+
current_display_format = next_item(
|
2709
|
+
display_formats, current_display_format
|
2710
|
+
)
|
2711
|
+
pause_menu = false
|
2712
|
+
else
|
2713
|
+
handle_selection(menu_entries, selection,
|
2714
|
+
current_display_format) do |item|
|
2715
|
+
yield item if block_given?
|
2716
|
+
end
|
2717
|
+
pause_menu = pause_after_selection
|
2718
|
+
end
|
2719
|
+
end
|
2720
|
+
end
|
2721
|
+
|
2722
|
+
def handle_selection(menu_entries, selection, current_display_format)
|
2723
|
+
selected_item = menu_entries.find do |entry|
|
2724
|
+
entry.send(current_display_format) == selection
|
2725
|
+
end
|
2726
|
+
yield selected_item if selected_item
|
2727
|
+
end
|
2728
|
+
|
2682
2729
|
# Iterates through blocks in a file, applying the provided block to each line.
|
2683
2730
|
# The iteration only occurs if the file exists.
|
2684
2731
|
# @yield [Symbol] :filter Yields to obtain selected messages for processing.
|
@@ -3209,6 +3256,13 @@ module MarkdownExec
|
|
3209
3256
|
end
|
3210
3257
|
end
|
3211
3258
|
|
3259
|
+
def next_item(list, current_item)
|
3260
|
+
index = list.index(current_item)
|
3261
|
+
return nil unless index # Return nil if the item is not in the list
|
3262
|
+
|
3263
|
+
list[(index + 1) % list.size] # Get the next item, wrap around if at the end
|
3264
|
+
end
|
3265
|
+
|
3212
3266
|
def next_state_append_code(selected, link_state, code_lines)
|
3213
3267
|
next_state_set_code(
|
3214
3268
|
selected,
|
@@ -4111,7 +4165,7 @@ module MarkdownExec
|
|
4111
4165
|
disabled = if fcb_title_groups.fetch(:type, '') == BlockType::YAML
|
4112
4166
|
TtyMenu::DISABLE
|
4113
4167
|
else
|
4114
|
-
|
4168
|
+
TtyMenu::ENABLE
|
4115
4169
|
end
|
4116
4170
|
|
4117
4171
|
MarkdownExec::FCB.new(
|
@@ -4237,11 +4291,11 @@ module MarkdownExec
|
|
4237
4291
|
@delegate_object.merge!(options)
|
4238
4292
|
end
|
4239
4293
|
|
4240
|
-
def vux_await_user_selection
|
4294
|
+
def vux_await_user_selection(prior_answer: @dml_block_selection)
|
4241
4295
|
@dml_block_state = load_cli_or_user_selected_block(
|
4242
4296
|
all_blocks: @dml_blocks_in_file,
|
4243
4297
|
menu_blocks: @dml_menu_blocks,
|
4244
|
-
prior_answer:
|
4298
|
+
prior_answer: prior_answer
|
4245
4299
|
)
|
4246
4300
|
if !@dml_block_state
|
4247
4301
|
# HashDelegator.error_handler('block_state missing', { abort: true })
|
@@ -4395,7 +4449,7 @@ module MarkdownExec
|
|
4395
4449
|
@dml_link_state.block_name.present?
|
4396
4450
|
@cli_block_name = @dml_link_state.block_name
|
4397
4451
|
@dml_now_using_cli = @run_state.source.block_name_from_cli
|
4398
|
-
@
|
4452
|
+
@dml_block_selection = nil
|
4399
4453
|
@dml_block_state = SelectedBlockMenuState.new
|
4400
4454
|
@doc_saved_lines_files = []
|
4401
4455
|
|
@@ -4713,7 +4767,9 @@ module MarkdownExec
|
|
4713
4767
|
else
|
4714
4768
|
# puts "? - Select a block to execute (or type #{$texit}
|
4715
4769
|
# to exit):"
|
4716
|
-
return :break if vux_await_user_selection
|
4770
|
+
return :break if vux_await_user_selection(
|
4771
|
+
prior_answer: @dml_block_selection
|
4772
|
+
) == :break
|
4717
4773
|
return :break if @dml_block_state.block.nil? # no block matched
|
4718
4774
|
end
|
4719
4775
|
# puts "! - Executing block: #{data}"
|
@@ -4763,7 +4819,13 @@ module MarkdownExec
|
|
4763
4819
|
block.dname.include?(prior_answer)
|
4764
4820
|
end&.name
|
4765
4821
|
when Struct
|
4766
|
-
|
4822
|
+
if prior_answer.id
|
4823
|
+
menu_items.find_index do |block|
|
4824
|
+
block[:id] == prior_answer.id
|
4825
|
+
end + 1
|
4826
|
+
else
|
4827
|
+
prior_answer.index || prior_answer.name
|
4828
|
+
end
|
4767
4829
|
end
|
4768
4830
|
# prior_answer value may not match if color is different from
|
4769
4831
|
# originating menu (opts changed while processing)
|
data/lib/mdoc.rb
CHANGED
@@ -85,14 +85,17 @@ module MarkdownExec
|
|
85
85
|
|
86
86
|
dependencies = collect_dependencies(nickname)
|
87
87
|
# !!t dependencies.count
|
88
|
-
all_dependency_names =
|
88
|
+
all_dependency_names =
|
89
|
+
collect_unique_names(dependencies).push(nickname).uniq
|
89
90
|
# !!t all_dependency_names.count
|
90
91
|
|
91
92
|
# select blocks in order of appearance in source documents
|
92
93
|
#
|
93
94
|
blocks = @table.select do |fcb|
|
94
95
|
# 2024-08-04 match nickname
|
95
|
-
all_dependency_names.include?(fcb.pub_name) ||
|
96
|
+
all_dependency_names.include?(fcb.pub_name) ||
|
97
|
+
all_dependency_names.include?(fcb.nickname) ||
|
98
|
+
all_dependency_names.include?(fcb.oname)
|
96
99
|
end
|
97
100
|
# !!t blocks.count
|
98
101
|
|
@@ -102,7 +105,10 @@ module MarkdownExec
|
|
102
105
|
blocks = blocks.map do |fcb|
|
103
106
|
# 2024-08-04 match oname for long block names
|
104
107
|
# 2024-08-04 match nickname
|
105
|
-
|
108
|
+
# may not exist if block name is duplicated
|
109
|
+
unmet_dependencies.delete(fcb.pub_name) ||
|
110
|
+
unmet_dependencies.delete(fcb.nickname) ||
|
111
|
+
unmet_dependencies.delete(fcb.oname)
|
106
112
|
if (call = fcb.call)
|
107
113
|
fcb1 = get_block_by_anyname("[#{call.match(/^%\((\S+) |\)/)[1]}]")
|
108
114
|
fcb1.cann = call
|
@@ -124,8 +130,10 @@ module MarkdownExec
|
|
124
130
|
# @param name [String] The name of the code block to start the collection from.
|
125
131
|
# @return [Array<String>] An array of strings containing the collected code blocks.
|
126
132
|
#
|
127
|
-
def collect_recursively_required_code(
|
128
|
-
|
133
|
+
def collect_recursively_required_code(
|
134
|
+
anyname:, block_source:,
|
135
|
+
label_body: true, label_format_above: nil, label_format_below: nil
|
136
|
+
)
|
129
137
|
block_search = collect_block_dependencies(anyname: anyname)
|
130
138
|
if block_search[:blocks]
|
131
139
|
blocks = collect_wrapped_blocks(block_search[:blocks])
|
@@ -150,8 +158,10 @@ module MarkdownExec
|
|
150
158
|
elsif fcb.type == BlockType::PORT
|
151
159
|
generate_env_variable_shell_commands(fcb)
|
152
160
|
elsif label_body
|
153
|
-
generate_label_body_code(
|
154
|
-
|
161
|
+
generate_label_body_code(
|
162
|
+
fcb, block_source,
|
163
|
+
label_format_above, label_format_below
|
164
|
+
)
|
155
165
|
else # raw body
|
156
166
|
fcb.body
|
157
167
|
end
|
@@ -230,9 +240,14 @@ module MarkdownExec
|
|
230
240
|
initialize: opts[:compressed_ids].nil?
|
231
241
|
) do |fcb, _hide, _collapsed_level|
|
232
242
|
# update fcb per state
|
233
|
-
|
234
|
-
|
235
|
-
|
243
|
+
next unless fcb.collapsible
|
244
|
+
|
245
|
+
fcb.s1decorated = fcb.s1decorated + ' ' +
|
246
|
+
(if fcb.collapse
|
247
|
+
opts[:menu_collapsible_symbol_collapsed]
|
248
|
+
else
|
249
|
+
opts[:menu_collapsible_symbol_expanded]
|
250
|
+
end)
|
236
251
|
end
|
237
252
|
opts[:compressed_ids] = collapser.compress_ids
|
238
253
|
opts[:expanded_ids] = collapser.expand_ids
|
@@ -240,7 +255,9 @@ module MarkdownExec
|
|
240
255
|
# remove
|
241
256
|
# . empty chrome between code; edges are same as blanks
|
242
257
|
#
|
243
|
-
select_elements_with_neighbor_conditions(selrows) do |prev_element,
|
258
|
+
select_elements_with_neighbor_conditions(selrows) do |prev_element,
|
259
|
+
current,
|
260
|
+
next_element|
|
244
261
|
!(current[:chrome] && !current.oname.present?) ||
|
245
262
|
!(!prev_element.nil? &&
|
246
263
|
prev_element.shell.present? &&
|
@@ -291,13 +308,17 @@ module MarkdownExec
|
|
291
308
|
|
292
309
|
label_above = if label_format_above.present?
|
293
310
|
format(label_format_above,
|
294
|
-
block_source.merge(
|
311
|
+
block_source.merge(
|
312
|
+
{ block_name: block_name_for_bash_comment }
|
313
|
+
))
|
295
314
|
else
|
296
315
|
nil
|
297
316
|
end
|
298
317
|
label_below = if label_format_below.present?
|
299
318
|
format(label_format_below,
|
300
|
-
block_source.merge(
|
319
|
+
block_source.merge(
|
320
|
+
{ block_name: block_name_for_bash_comment }
|
321
|
+
))
|
301
322
|
else
|
302
323
|
nil
|
303
324
|
end
|
@@ -415,8 +436,11 @@ module MarkdownExec
|
|
415
436
|
memo
|
416
437
|
end
|
417
438
|
|
418
|
-
def select_elements_with_neighbor_conditions(
|
419
|
-
|
439
|
+
def select_elements_with_neighbor_conditions(
|
440
|
+
array,
|
441
|
+
last_selected_placeholder = nil,
|
442
|
+
next_selected_placeholder = nil
|
443
|
+
)
|
420
444
|
selected_elements = []
|
421
445
|
last_selected = last_selected_placeholder
|
422
446
|
|
@@ -463,8 +487,10 @@ if $PROGRAM_NAME == __FILE__
|
|
463
487
|
end if false
|
464
488
|
|
465
489
|
def test_collect_dependencies_with_valid_source
|
466
|
-
@mdoc.stubs(:get_block_by_anyname)
|
467
|
-
|
490
|
+
@mdoc.stubs(:get_block_by_anyname)
|
491
|
+
.with('source1').returns(OpenStruct.new(reqs: ['source2']))
|
492
|
+
@mdoc.stubs(:get_block_by_anyname)
|
493
|
+
.with('source2').returns(OpenStruct.new(reqs: []))
|
468
494
|
|
469
495
|
expected = { 'source1' => ['source2'], 'source2' => [] }
|
470
496
|
assert_equal expected, @mdoc.collect_dependencies('source1')
|
@@ -535,14 +561,17 @@ if $PROGRAM_NAME == __FILE__
|
|
535
561
|
end
|
536
562
|
|
537
563
|
def test_fcbs_per_options
|
538
|
-
opts = { hide_blocks_by_name: true,
|
564
|
+
opts = { hide_blocks_by_name: true,
|
565
|
+
block_name_hidden_match: 'block1' }
|
539
566
|
result = @doc.fcbs_per_options(opts)
|
540
567
|
assert_equal [@table[1], @table[2]], result
|
541
568
|
end if false ### broken test
|
542
569
|
|
543
570
|
def test_recursively_required
|
544
571
|
result = @doc.recursively_required_hash('block3')
|
545
|
-
assert_equal ({ 'block3' => ['block1'],
|
572
|
+
assert_equal ({ 'block3' => ['block1'],
|
573
|
+
'block1' => ['block2'],
|
574
|
+
'block2' => nil }),
|
546
575
|
result
|
547
576
|
|
548
577
|
result_no_reqs = @doc.recursively_required_hash(nil)
|
@@ -585,8 +614,9 @@ if $PROGRAM_NAME == __FILE__
|
|
585
614
|
# Test case 3: blocks with missing wraps
|
586
615
|
assert_equal(
|
587
616
|
%w[block4],
|
588
|
-
@mdoc.collect_wrapped_blocks(
|
589
|
-
|
617
|
+
@mdoc.collect_wrapped_blocks(
|
618
|
+
[OpenStruct.new(oname: 'block4', wraps: ['wrap4'])]
|
619
|
+
).map(&:oname)
|
590
620
|
)
|
591
621
|
end
|
592
622
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdown_exec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.8.
|
4
|
+
version: 2.8.1
|
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-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|
@@ -108,6 +108,10 @@ files:
|
|
108
108
|
- assets/select_a_file.png
|
109
109
|
- bats/bats.bats
|
110
110
|
- bats/block-type-opts.bats
|
111
|
+
- bats/block-type-ux-auto.bats
|
112
|
+
- bats/block-type-ux-exec.bats
|
113
|
+
- bats/block-type-ux-row-format.bats
|
114
|
+
- bats/block-type-ux-transform.bats
|
111
115
|
- bats/block-type-vars.bats
|
112
116
|
- bats/block-types.bats
|
113
117
|
- bats/border.bats
|
@@ -139,6 +143,10 @@ files:
|
|
139
143
|
- docs/dev/block-type-bash.md
|
140
144
|
- docs/dev/block-type-opts.md
|
141
145
|
- docs/dev/block-type-port.md
|
146
|
+
- docs/dev/block-type-ux-auto.md
|
147
|
+
- docs/dev/block-type-ux-exec.md
|
148
|
+
- docs/dev/block-type-ux-row-format.md
|
149
|
+
- docs/dev/block-type-ux-transform.md
|
142
150
|
- docs/dev/block-type-vars.md
|
143
151
|
- docs/dev/border.md
|
144
152
|
- docs/dev/command-substitution.md
|