markdown_exec 3.3.0 → 3.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +27 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -1
- data/README.md +262 -116
- data/Rakefile +2 -1
- data/bats/block-type-shell-require-ux.bats +15 -0
- data/bats/block-type-ux-auto.bats +1 -1
- data/bats/block-type-ux-default.bats +1 -1
- data/bats/block-type-ux-echo-hash.bats +2 -2
- data/bats/block-type-ux-exec-hash.bats +2 -2
- data/bats/block-type-ux-exec.bats +1 -1
- data/bats/block-type-ux-no-name.bats +8 -0
- data/bats/block-type-ux-require-context.bats +14 -0
- data/bats/block-type-ux-row-format.bats +1 -1
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/command-substitution-options.bats +2 -2
- data/bats/import-directive-line-continuation.bats +9 -0
- data/bats/import-directive-parameter-symbols.bats +1 -1
- data/bats/import-parameter-symbols.bats +1 -1
- data/bats/option-expansion.bats +1 -1
- data/bats/options.bats +2 -2
- data/bats/table-column-truncate.bats +1 -1
- data/bats/table.bats +1 -1
- data/bats/test_helper.bash +4 -3
- data/demo/trap.demo1.gif +0 -0
- data/demo/trap.demo1.mp4 +0 -0
- data/docs/dev/block-type-shell-require-ux.md +18 -0
- data/docs/dev/block-type-ux-format.md +10 -0
- data/docs/dev/block-type-ux-no-name.md +17 -0
- data/docs/dev/block-type-ux-require-context.md +32 -0
- data/docs/dev/block-type-ux-require.md +8 -4
- data/docs/dev/block-type-ux-row-format.md +1 -1
- data/docs/dev/import-directive-line-continuation.md +5 -0
- data/docs/dev/import-directive-parameter-symbols.md +0 -2
- data/docs/dev/import-parameter-symbols-template.md +7 -5
- data/docs/dev/import-parameter-symbols.md +10 -2
- data/docs/dev/table-column-truncate.md +1 -1
- data/examples/colors.md +31 -29
- data/lib/cached_nested_file_reader.rb +31 -51
- data/lib/command_result.rb +5 -5
- data/lib/constants.rb +3 -1
- data/lib/fcb.rb +22 -8
- data/lib/format_table.rb +22 -7
- data/lib/hash_delegator.rb +77 -33
- data/lib/link_history.rb +1 -1
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/menu.src.yml +47 -38
- data/lib/menu.yml +43 -34
- data/lib/parameter_expansion.rb +918 -0
- data/lib/parse_animation_to_tts.rb +4417 -0
- data/lib/resize_terminal.rb +19 -16
- data/lib/ww.rb +493 -15
- metadata +15 -2
|
@@ -4,5 +4,5 @@ load 'test_helper'
|
|
|
4
4
|
|
|
5
5
|
@test 'Transformed output of executed commands' {
|
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-transform.md \
|
|
7
|
-
'_Execution output has a trailing newline._Var0=
|
|
7
|
+
'_Execution output has a trailing newline._Var0=markdown_exec__ 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 0a __With validate and transform, output has no newline._Var1=markdown_exec_ 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 __With transform :chomp, output has no newline._Var2=markdown_exec_ 6d 61 72 6b 64 6f 77 6e 5f 65 78 65 63 __With transform :upcase, output is in upper case w/ newline._Var3=MARKDOWN_EXEC__ 4d 41 52 4b 44 4f 57 4e 5f 45 58 45 43 0a '
|
|
8
8
|
}
|
|
@@ -5,10 +5,10 @@ load 'test_helper'
|
|
|
5
5
|
@test 'Operator $' {
|
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/command-substitution-options.md \
|
|
7
7
|
'operator_$' \
|
|
8
|
-
'Command substitution__The current value of environment variable Common_Name_is displayed using two different operators._The command echo $SHLVL is executed via command_substitution, using two different operators.__|
|
|
8
|
+
'Command substitution__The current value of environment variable Common_Name_is displayed using two different operators._The command echo $SHLVL is executed via command_substitution, using two different operators.__| Operator | Variable Expansion | Command Substitution |_| -------- | ------------------ | -------------------- |_| $ | Tapanuli Orangutan | Pongo tapanuliensis |_| @ | @{Common_Name} | @(echo $Species) |__Toggle between operators.__operator_$__operator_@'
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
@test 'Operator @' {
|
|
12
12
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/command-substitution-options.md \
|
|
13
|
-
'Command substitution__The current value of environment variable Common_Name_is displayed using two different operators._The command echo $SHLVL is executed via command_substitution, using two different operators.__|
|
|
13
|
+
'Command substitution__The current value of environment variable Common_Name_is displayed using two different operators._The command echo $SHLVL is executed via command_substitution, using two different operators.__| Operator | Variable Expansion | Command Substitution |_| -------- | ------------------ | -------------------- |_| $ | ${Common_Name} | $(echo $Species) |_| @ | Tapanuli Orangutan | Pongo tapanuliensis |__Toggle between operators.__operator_$__operator_@'
|
|
14
14
|
}
|
|
@@ -5,5 +5,5 @@ load 'test_helper'
|
|
|
5
5
|
@test '' {
|
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/import-directive-parameter-symbols.md \
|
|
7
7
|
--blocks dname \
|
|
8
|
-
'Stem: U1_Species: Illacme
|
|
8
|
+
'Stem: U1_Species: Illacme tobini_Stem: U2_Species: Hydrodynastes bicinctus'
|
|
9
9
|
}
|
|
@@ -4,5 +4,5 @@ load 'test_helper'
|
|
|
4
4
|
|
|
5
5
|
@test 'Initial values' {
|
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/import-parameter-symbols.md \
|
|
7
|
-
'COMMON_NAME=Tapanuli
|
|
7
|
+
'COMMON_NAME=Tapanuli Orangutan_Evaluated expression: Tapanuli Orangutan_echo "Evaluated expression: $(printf %s "$COMMON_NAME")"__Raw literal: Tapanuli Orangutan_echo "Raw literal: Tapanuli Orangutan"__Force-quoted literal: Tapanuli Orangutan_echo "Force-quoted literal: Tapanuli Orangutan"__Variable reference: Tapanuli Orangutan_echo "Variable reference: ${COMMON_NAME}"'
|
|
8
8
|
}
|
data/bats/option-expansion.bats
CHANGED
|
@@ -4,5 +4,5 @@ load 'test_helper'
|
|
|
4
4
|
|
|
5
5
|
@test '' {
|
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/option-expansion.md \
|
|
7
|
-
'_|
|
|
7
|
+
'_| Opti | Description | Valu | Va | Defau |_| ---- | ---------------------------- | ---- | -- | ----- |_| scre | Screen width for document an | 2 | 64 | 0 |_| tabl | | 5 | fa | true |'
|
|
8
8
|
}
|
data/bats/options.bats
CHANGED
|
@@ -30,13 +30,13 @@ load 'test_helper'
|
|
|
30
30
|
@test 'Options - list blocks' {
|
|
31
31
|
BATS_OUTPUT_FILTER=A
|
|
32
32
|
spec_mde_args_expect --list-blocks-message oname --list-blocks-type 0 examples/colors.md --list-blocks \
|
|
33
|
-
'load_colors load_colors2
|
|
33
|
+
'load_colors load_colors2 Unspecified1 Unknown1 Bash1 Edit-inherited-blocks History1 Link1 Load1 Opts1 Port1 Save1 Vars1'
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
@test 'Options - list blocks, eval' {
|
|
37
37
|
BATS_OUTPUT_FILTER=A
|
|
38
38
|
spec_mde_args_expect --list-blocks-eval block.oname examples/colors.md --list-blocks \
|
|
39
|
-
'load_colors load_colors2
|
|
39
|
+
'load_colors load_colors2 Unspecified1 Unknown1 Bash1 Edit-inherited-blocks History1 Link1 Load1 Opts1 Port1 Save1 Vars1'
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
@test 'Options - how' {
|
|
@@ -4,5 +4,5 @@ load 'test_helper'
|
|
|
4
4
|
|
|
5
5
|
@test 'Tables - truncate columns' {
|
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/table-column-truncate.md \
|
|
7
|
-
'DEMONSTRATE TRUNCATION OF TEXT IN TABLE CELLS__| Common Name
|
|
7
|
+
'DEMONSTRATE TRUNCATION OF TEXT IN TABLE CELLS__| Common Name | Species | Genus | Family | Year Discover |_| ------------------- | ------------------ | -------- | ----------- | ------------- |_| Tapanuli Orangutan | Pongo tapanuliensi | Pongo | Hominidae | 2017 |_| Psychedelic Frogfis | Histiophryne psych | Histioph | Antennariid | 2009 |_| Ruby Seadragon | Phyllopteryx dewys | Phyllopt | Syngnathida | 2015 |_| Illacme tobini (Mil | Illacme tobini | Illacme | Siphonorhin | 2016 |_| Spiny Dandelion | Taraxacum japonicu | Taraxacu | Asteraceae | 2022 |_'
|
|
8
8
|
}
|
data/bats/table.bats
CHANGED
|
@@ -4,7 +4,7 @@ load 'test_helper'
|
|
|
4
4
|
|
|
5
5
|
@test 'Tables - indented' {
|
|
6
6
|
spec_mde_xansi_dname_doc_blocks_expect docs/dev/table-indent.md \
|
|
7
|
-
'DEMONSTRATE TABLE INDENTATION__Table flush at left._Centered columns._| Common Name |
|
|
7
|
+
'DEMONSTRATE TABLE INDENTATION__Table flush at left._Centered columns._| Common Name | Species | Genus | Family | Year Discovered |_| ------------------ | ----------------------- | ----------- | ------------ | --------------- |_| Tapanuli Orangutan | Pongo tapanuliensis | Pongo | Hominidae | 2017 |_| Psychedelic Frogfi | Histiophryne psychedeli | Histiophryn | Antennariida | 2009 |_| Ruby Seadragon | Phyllopteryx dewysea | Phylloptery | Syngnathidae | 2015 |__ Table indented with two spaces._ Left-justified columns._ | Common Name | Species | Genus | Family | Year Discovered |_ | -------------------------- | -------------- | ------- | --------------- | --------------- |_ | Illacme tobini (Millipede) | Illacme tobini | Illacme | Siphonorhinidae | 2016 |__ Table indented with one tab._ Right-justified columns._ | Common Name | Species | Genus | Family | Year Discovered |_ | --------------- | ------------------- | --------- | ---------- | --------------- |_ | Spiny Dandelion | Taraxacum japonicum | Taraxacum | Asteraceae | 2022 |'
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
@test 'Tables - invalid' {
|
data/bats/test_helper.bash
CHANGED
|
@@ -7,6 +7,7 @@ EXIT_MENU=__Exit # name of menu Exit option
|
|
|
7
7
|
# • expected byte (0xHEX) and printable character (or “.”)
|
|
8
8
|
# • actual byte (0xHEX) and printable character (or “.”)
|
|
9
9
|
compare_bytes () {
|
|
10
|
+
readonly line_count=16
|
|
10
11
|
set +e
|
|
11
12
|
local mode="$1"; shift
|
|
12
13
|
if [[ "$mode" == "--file" ]]; then
|
|
@@ -19,13 +20,13 @@ compare_bytes () {
|
|
|
19
20
|
# feed the two strings into cmp via process-substitution
|
|
20
21
|
cmp --verbose <(printf '%s' "$live") <(printf '%s' "$expect")
|
|
21
22
|
fi |
|
|
22
|
-
head -n
|
|
23
|
+
head -n $line_count |
|
|
23
24
|
gawk '{
|
|
24
25
|
live = strtonum(0 $2)
|
|
25
26
|
expect = strtonum(0 $3)
|
|
26
27
|
offset = $1 - 1
|
|
27
|
-
printf "Offset 0x%X (%4d):
|
|
28
|
-
offset, offset,
|
|
28
|
+
printf "Offset 0x%X (%4d): expect \"%c\" 0x%02X (%3d) vs output \"%c\" 0x%02X (%3d)\n", \
|
|
29
|
+
offset, offset, expect, expect, expect, live, live, live
|
|
29
30
|
}'
|
|
30
31
|
set -e
|
|
31
32
|
}
|
data/demo/trap.demo1.gif
ADDED
|
Binary file
|
data/demo/trap.demo1.mp4
ADDED
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/ No blocks are evaluated at initialization.
|
|
2
|
+
/ When the shell block is activated, the UX block is required.
|
|
3
|
+
```bash :require-a-UX-block +[ux1]
|
|
4
|
+
ENTITY='Mythical Monkey'
|
|
5
|
+
```
|
|
6
|
+
/ Display variables set in the UX block.
|
|
7
|
+
${FIRST}
|
|
8
|
+
${LAST}
|
|
9
|
+
/ Parse and copy the name into variables.
|
|
10
|
+
```ux :[ux1]
|
|
11
|
+
echo:
|
|
12
|
+
FIRST: '${ENTITY%% *}'
|
|
13
|
+
LAST: '${ENTITY##* }'
|
|
14
|
+
FULL_NAME: '$ENTITY'
|
|
15
|
+
init: false
|
|
16
|
+
readonly: true
|
|
17
|
+
```
|
|
18
|
+
@import bats-document-configuration.md
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/ This automatic block sets multiple variables and displays the first variable.
|
|
2
|
+
```ux
|
|
3
|
+
echo:
|
|
4
|
+
BASENAME1: "$(basename `pwd`)"
|
|
5
|
+
DOCUMENTS1: "${BASENAME1%%_*}"
|
|
6
|
+
OPERATION1: "${BASENAME1##*_}"
|
|
7
|
+
```
|
|
8
|
+
```ux
|
|
9
|
+
exec:
|
|
10
|
+
BASENAME2: >-
|
|
11
|
+
basename `pwd`
|
|
12
|
+
DOCUMENTS2: >-
|
|
13
|
+
echo "${BASENAME2%%_*}"
|
|
14
|
+
OPERATION2: >-
|
|
15
|
+
echo "${BASENAME2##*_}"
|
|
16
|
+
```
|
|
17
|
+
@import bats-document-configuration.md
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/ Neither block is evaluated at initialization.
|
|
2
|
+
/ When the first UX block is activated, it is evaluated.
|
|
3
|
+
/ The variable set in the first UX block is available to the second,
|
|
4
|
+
/ which is required by the first, resulting in its evaluation.
|
|
5
|
+
```ux :[ux1] +[ux2] +(ENTITY)
|
|
6
|
+
act: :echo
|
|
7
|
+
echo:
|
|
8
|
+
UX1: '$ENTITY'
|
|
9
|
+
format: |-
|
|
10
|
+
Get the common name...
|
|
11
|
+
init: false
|
|
12
|
+
```
|
|
13
|
+
/ The shell required code and the first evaluated UX block are the context
|
|
14
|
+
/ when the the `echo` expressions are being evaluated in the second UX block.
|
|
15
|
+
/ The first evaluated UX block is the context when the `format` value is being expanded.
|
|
16
|
+
```ux :[ux2]
|
|
17
|
+
act: :echo
|
|
18
|
+
echo:
|
|
19
|
+
UX2: '$UX1'
|
|
20
|
+
ENTITY2: '$ENTITY'
|
|
21
|
+
format: |-
|
|
22
|
+
Entity: ${ENTITY}
|
|
23
|
+
ENTITY2: ${ENTITY2}
|
|
24
|
+
UX1: ${UX1}
|
|
25
|
+
Common name: ${UX2}
|
|
26
|
+
init: false
|
|
27
|
+
readonly: true
|
|
28
|
+
```
|
|
29
|
+
```bash :(ENTITY)
|
|
30
|
+
ENTITY='Mythical Monkey'
|
|
31
|
+
```
|
|
32
|
+
@import bats-document-configuration.md
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/ This is an hidden shell block that is required by UX blocks.
|
|
2
|
-
``` :(shell)
|
|
3
|
-
ENTITY='Pongo tapanuliensis,Pongo'
|
|
4
|
-
```
|
|
5
1
|
```ux +(shell)
|
|
6
2
|
echo: "${ENTITY%%,*}"
|
|
7
3
|
force: true
|
|
@@ -24,6 +20,14 @@ echo: "$NAME"
|
|
|
24
20
|
force: true
|
|
25
21
|
name: NAME2
|
|
26
22
|
```
|
|
23
|
+
/
|
|
24
|
+
/ This is a hidden shell block that is required by a UX block.
|
|
25
|
+
/ All shell blocks required by a UX block are collected in a sequence
|
|
26
|
+
/ that is the context for the evaluation of the expressions in the UX block.
|
|
27
|
+
``` :(shell)
|
|
28
|
+
ENTITY='Pongo tapanuliensis,Pongo'
|
|
29
|
+
```
|
|
30
|
+
/
|
|
27
31
|
/ This block is not visible. Execute to display the inherited lines for testing.
|
|
28
32
|
```opts :(menu_with_inherited_lines)
|
|
29
33
|
menu_with_inherited_lines: true
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
/ use MDE 3.3.0 import parameter symbols
|
|
2
2
|
/
|
|
3
3
|
@import ./import/parameter-symbols.md __PS_STEM_SPECIES:q='Illacme tobini' __PS_STEM_GENUS:q=Illacme PS_STEM=U1
|
|
4
|
-
Genus: ${__U1_GENUS}
|
|
5
4
|
/
|
|
6
5
|
@import ./import/parameter-symbols.md __PS_STEM_SPECIES:q='Hydrodynastes bicinctus' __PS_STEM_GENUS:q=Hydrodynastes PS_STEM=U2
|
|
7
|
-
Genus: ${__U2_GENUS}
|
|
8
6
|
/
|
|
9
7
|
@import ./bats-document-configuration.md
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
/ 2025-11-13 the name of the variable generated
|
|
2
|
+
/ changes on every load is not predictable
|
|
3
|
+
/**Command substitution:** `NAMEC`
|
|
4
|
+
/```bash
|
|
5
|
+
/echo "Command substitution: NAMEC"
|
|
6
|
+
/```
|
|
7
|
+
/
|
|
6
8
|
**Evaluated expression:** `NAMEE`
|
|
7
9
|
```bash
|
|
8
10
|
echo "Evaluated expression: NAMEE"
|
|
@@ -2,5 +2,13 @@
|
|
|
2
2
|
echo: Tapanuli Orangutan
|
|
3
3
|
name: COMMON_NAME
|
|
4
4
|
```
|
|
5
|
-
@import import-parameter-symbols-template.md
|
|
6
|
-
|
|
5
|
+
@import import-parameter-symbols-template.md \
|
|
6
|
+
NAMEC:cq='printf %s "$COMMON_NAME"' \
|
|
7
|
+
NAMEE:eq=$COMMON_NAME \
|
|
8
|
+
NAMEL="Tapanuli Orangutan" \
|
|
9
|
+
NAMEQ:qq="Tapanuli Orangutan" \
|
|
10
|
+
NAMEV:vq=COMMON_NAME
|
|
11
|
+
@import bats-document-configuration.md
|
|
12
|
+
```opts :(document_opts)
|
|
13
|
+
dump_inherited_lines: false
|
|
14
|
+
```
|
data/examples/colors.md
CHANGED
|
@@ -1,27 +1,19 @@
|
|
|
1
1
|
# Demo configuring options
|
|
2
|
-
|
|
2
|
+
/ v2025-09-30
|
|
3
3
|
::: These Opts blocks set the color for all elements.
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
/
|
|
8
|
-
/
|
|
9
|
-
/
|
|
10
|
-
/
|
|
11
|
-
/ 00ff00 green - prompt
|
|
12
|
-
/ 00ff7f spring green - input frame
|
|
13
|
-
/ 00ffff cyan - menu text
|
|
14
|
-
/ 007fff azure - menu frame
|
|
15
|
-
/ 0000ff blue
|
|
16
|
-
/ 7f00ff violet - opts frame
|
|
17
|
-
/ ff00ff magenta - opts text
|
|
18
|
-
/ ff007f rose - exception frame
|
|
19
|
-
|
|
4
|
+
/ blue fg_rgbh_00_00_FF
|
|
5
|
+
/ green fg_rgbh_00_FF_00
|
|
6
|
+
/ indigo fg_rgbh_4B_00_82
|
|
7
|
+
/ orange fg_rgbh_FF_7F_00
|
|
8
|
+
/ red fg_rgbh_FF_00_00
|
|
9
|
+
/ violet fg_rgbh_94_00_D3
|
|
10
|
+
/ yellow fg_rgbh_FF_FF_00
|
|
20
11
|
```opts :load_colors
|
|
21
12
|
exception_color_detail: fg_rgbh_1f_00_7f
|
|
22
13
|
exception_color_name: fg_rgbh_1f_00_00
|
|
23
14
|
execution_report_preview_frame_color: fg_rgbh_7f_1f_00
|
|
24
15
|
menu_bash_color: fg_rgbh_00_c0_c0
|
|
16
|
+
menu_block_color: fg_rgbh_47_ce_eb
|
|
25
17
|
menu_chrome_color: fg_rgbh_40_c0_c0
|
|
26
18
|
menu_divider_color: fg_rgbh_80_d0_c0
|
|
27
19
|
menu_edit_color: fg_rgbh_e0_e0_20
|
|
@@ -44,11 +36,13 @@ script_preview_frame_color: fg_rgbh_7f_1f_00
|
|
|
44
36
|
warning_color: fg_rgbh_1f_7f_00
|
|
45
37
|
```
|
|
46
38
|
|
|
39
|
+
/ more green, less blue
|
|
47
40
|
```opts :load_colors2
|
|
48
41
|
exception_color_detail: fg_rgbh_ff_00_7f
|
|
49
42
|
exception_color_name: fg_rgbh_ff_00_00
|
|
50
43
|
execution_report_preview_frame_color: fg_rgbh_7f_ff_00
|
|
51
44
|
menu_bash_color: fg_rgbh_00_c0_c0
|
|
45
|
+
menu_block_color: fg_rgbh_47_fe_bb
|
|
52
46
|
menu_chrome_color: fg_rgbh_40_c0_c0
|
|
53
47
|
menu_divider_color: fg_rgbh_80_d0_c0
|
|
54
48
|
menu_edit_color: fg_rgbh_e2_e2_20
|
|
@@ -72,12 +66,18 @@ script_preview_frame_color: fg_rgbh_7f_ff_00
|
|
|
72
66
|
warning_color: fg_rgbh_ff_7f_00
|
|
73
67
|
```
|
|
74
68
|
|
|
75
|
-
:::
|
|
69
|
+
::: Divider color
|
|
70
|
+
|
|
71
|
+
::: Fenced code blocks of different types
|
|
72
|
+
Each block has a name. Its name is decorated according to the type of the block.
|
|
73
|
+
``` :Unspecified1
|
|
76
74
|
```
|
|
75
|
+
```unknown :Unknown1
|
|
77
76
|
```
|
|
78
77
|
```bash :Bash1
|
|
79
78
|
```
|
|
80
|
-
|
|
79
|
+
/ Chrome decoration
|
|
80
|
+
```edit :Edit-inherited-blocks
|
|
81
81
|
```
|
|
82
82
|
```history :History1
|
|
83
83
|
```
|
|
@@ -85,20 +85,22 @@ warning_color: fg_rgbh_ff_7f_00
|
|
|
85
85
|
```
|
|
86
86
|
```load :Load1
|
|
87
87
|
```
|
|
88
|
+
/ Note decoration
|
|
89
|
+
A Note
|
|
90
|
+
/ Opts decoration
|
|
88
91
|
```opts :Opts1
|
|
89
92
|
```
|
|
90
93
|
```port :Port1
|
|
91
94
|
```
|
|
95
|
+
/ Save decoration
|
|
92
96
|
```save :Save1
|
|
93
97
|
```
|
|
94
|
-
|
|
98
|
+
/ Task decoration
|
|
99
|
+
[ ] Task
|
|
100
|
+
/ UX decoration
|
|
101
|
+
```ux
|
|
102
|
+
format: UX-1
|
|
95
103
|
```
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
/ green; fg_rgbh_00_FF_00
|
|
100
|
-
/ indigo; fg_rgbh_4B_00_82
|
|
101
|
-
/ orange; fg_rgbh_FF_7F_00
|
|
102
|
-
/ red; fg_rgbh_FF_00_00
|
|
103
|
-
/ violet; fg_rgbh_94_00_D3
|
|
104
|
-
/ yellow; fg_rgbh_FF_FF_00
|
|
104
|
+
/ Vars decoration
|
|
105
|
+
```vars :Vars1
|
|
106
|
+
```
|
|
@@ -89,21 +89,38 @@ class CachedNestedFileReader
|
|
|
89
89
|
|
|
90
90
|
directory_path = File.dirname(filename)
|
|
91
91
|
processed_lines = []
|
|
92
|
-
|
|
92
|
+
continued_line = nil # continued import directive
|
|
93
|
+
File.readlines(filename, chomp: true).each.with_index do |segment, ind|
|
|
93
94
|
wwt :readline, 'depth:', depth, 'filename:', filename, 'ind:', ind,
|
|
94
|
-
'
|
|
95
|
-
|
|
95
|
+
'segment:', segment
|
|
96
|
+
|
|
97
|
+
if continued_line || (Regexp.new(@import_directive_line_pattern) =~ segment)
|
|
98
|
+
line = (continued_line || '') + segment
|
|
99
|
+
# if segment ends in a continuation, prepend to next line
|
|
100
|
+
if line.end_with?('\\')
|
|
101
|
+
continued_line = line.chomp('\\')
|
|
102
|
+
next
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
continued_line = nil
|
|
106
|
+
|
|
107
|
+
# apply substitutions to the @import line
|
|
108
|
+
line_sub1 = apply_line_substitutions(line, substitutions,
|
|
109
|
+
use_template_delimiters)
|
|
110
|
+
|
|
111
|
+
# parse the @import line
|
|
112
|
+
Regexp.new(@import_directive_line_pattern) =~ line_sub1
|
|
96
113
|
name_strip = $~[:name].strip
|
|
97
114
|
params_string = $~[:params] || ''
|
|
98
115
|
import_indention = indention + $~[:indention]
|
|
99
|
-
|
|
100
116
|
# Parse parameters for text substitution
|
|
101
117
|
import_substitutions, add_code = parse_import_params(params_string)
|
|
118
|
+
|
|
102
119
|
if add_code
|
|
103
120
|
# strings as NestedLines
|
|
104
|
-
add_lines = add_code.map.with_index do |
|
|
121
|
+
add_lines = add_code.map.with_index do |line2, ind2|
|
|
105
122
|
nested_line = NestedLine.new(
|
|
106
|
-
|
|
123
|
+
line2,
|
|
107
124
|
depth + 1,
|
|
108
125
|
import_indention,
|
|
109
126
|
filename,
|
|
@@ -161,7 +178,7 @@ class CachedNestedFileReader
|
|
|
161
178
|
processed_lines += processed_imported_lines
|
|
162
179
|
else
|
|
163
180
|
# Apply substitutions to the current line
|
|
164
|
-
substituted_line = apply_line_substitutions(
|
|
181
|
+
substituted_line = apply_line_substitutions(segment, substitutions,
|
|
165
182
|
use_template_delimiters)
|
|
166
183
|
nested_line = NestedLine.new(substituted_line, depth, indention,
|
|
167
184
|
filename, ind)
|
|
@@ -175,6 +192,8 @@ class CachedNestedFileReader
|
|
|
175
192
|
rescue Errno::ENOENT => err
|
|
176
193
|
warn_format('readlines', "#{err} @@ #{context}",
|
|
177
194
|
{ abort: true })
|
|
195
|
+
rescue StandardError
|
|
196
|
+
wwe $!
|
|
178
197
|
end
|
|
179
198
|
|
|
180
199
|
private
|
|
@@ -208,53 +227,14 @@ class CachedNestedFileReader
|
|
|
208
227
|
scanned_params.each do |key, op, value|
|
|
209
228
|
wwt :import, 'key:', key, 'op:', op, 'value:', value
|
|
210
229
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
when @symbol_command_substitution,
|
|
215
|
-
@symbol_evaluated_expression,
|
|
216
|
-
@symbol_force_quoted_literal,
|
|
217
|
-
@symbol_variable_reference
|
|
218
|
-
# perform all substitutions per equal_op_params
|
|
219
|
-
equal_op_params.each do |equal_key, _equal_op, equal_value|
|
|
220
|
-
varname = varname.gsub(equal_key, equal_value)
|
|
221
|
-
end
|
|
222
|
-
wwt :import_key, 'varname:', varname
|
|
223
|
-
end
|
|
230
|
+
require_relative 'parameter_expansion'
|
|
231
|
+
expansion, new_var = ParameterExpansion.expand_parameter(key, op[1..-2], value)
|
|
232
|
+
value = expansion
|
|
224
233
|
|
|
225
|
-
|
|
226
|
-
when @symbol_raw_literal
|
|
227
|
-
# skip replacement of equal values otherwise,
|
|
228
|
-
# the text is not available for other substitutions
|
|
229
|
-
next unless key != value
|
|
230
|
-
|
|
231
|
-
# replace the literal below
|
|
232
|
-
when @symbol_command_substitution
|
|
233
|
-
# add code to set the variable to the value of the parameter
|
|
234
|
-
add_code += shell_code_block_for_assignment(
|
|
235
|
-
varname, %($(#{value}))
|
|
236
|
-
)
|
|
237
|
-
# replace key with expansion of the added variable
|
|
238
|
-
value = "${#{varname}}"
|
|
239
|
-
when @symbol_evaluated_expression
|
|
240
|
-
# add code to set the variable to the value of the parameter
|
|
241
|
-
add_code += shell_code_block_for_assignment(
|
|
242
|
-
varname, %("#{value}")
|
|
243
|
-
)
|
|
244
|
-
# replace key with expansion of the added variable
|
|
245
|
-
value = "${#{varname}}"
|
|
246
|
-
when @symbol_force_quoted_literal
|
|
247
|
-
# add code to set the variable to the value of the parameter
|
|
234
|
+
unless new_var.nil?
|
|
248
235
|
add_code += shell_code_block_for_assignment(
|
|
249
|
-
|
|
236
|
+
new_var.name, Shellwords.escape(new_var.assignment_code)
|
|
250
237
|
)
|
|
251
|
-
# replace key with expansion of the added variable
|
|
252
|
-
value = "${#{varname}}"
|
|
253
|
-
when @symbol_variable_reference
|
|
254
|
-
# variable exists
|
|
255
|
-
value = "${#{value}}"
|
|
256
|
-
else
|
|
257
|
-
wwe "Invalid op '#{op}'"
|
|
258
238
|
end
|
|
259
239
|
|
|
260
240
|
params[key] = value
|
data/lib/command_result.rb
CHANGED
|
@@ -33,11 +33,11 @@ class CommandResult
|
|
|
33
33
|
exit_status.zero?
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
def new_lines
|
|
37
|
+
value = @attributes[:new_lines] || []
|
|
38
|
+
ww caller.deref[0..4], value
|
|
39
|
+
value
|
|
40
|
+
end
|
|
41
41
|
|
|
42
42
|
# # trap assignment to new_lines
|
|
43
43
|
# def new_lines=(value)
|
data/lib/constants.rb
CHANGED
|
@@ -35,7 +35,9 @@ BLOCK_TYPE_COLOR_OPTIONS = {
|
|
|
35
35
|
:readonly => :menu_ux_color_readonly,
|
|
36
36
|
true => :menu_ux_color
|
|
37
37
|
},
|
|
38
|
-
BlockType::VARS => :menu_vars_color
|
|
38
|
+
BlockType::VARS => :menu_vars_color,
|
|
39
|
+
# default for remaining block types
|
|
40
|
+
true => :menu_block_color
|
|
39
41
|
}.freeze
|
|
40
42
|
|
|
41
43
|
COLLAPSIBLE_SYMBOL_COLLAPSED = '⬢' # '<+>' # '∆'
|
data/lib/fcb.rb
CHANGED
|
@@ -7,15 +7,23 @@ require_relative 'namer'
|
|
|
7
7
|
BT_UX_FLD_REQUIRED = 'required'
|
|
8
8
|
def parse_yaml_of_ux_block(
|
|
9
9
|
data,
|
|
10
|
-
menu_format: nil,
|
|
11
10
|
prompt: nil,
|
|
12
11
|
validate: nil
|
|
13
12
|
)
|
|
14
|
-
export = data['export']
|
|
15
|
-
export = data if export.nil?
|
|
16
|
-
name = export['name']
|
|
13
|
+
export = data if (export = data['export']).nil?
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
# a single variable name is required to display a single value
|
|
16
|
+
menu_format = export['format'] || export['menu_format']
|
|
17
|
+
name = export['name']
|
|
18
|
+
# if name is missing, use the last key in the echo or exec hashes
|
|
19
|
+
if !name&.present?
|
|
20
|
+
name = if export['echo'].is_a? Hash
|
|
21
|
+
export['echo'].keys.last
|
|
22
|
+
elsif export['exec'].is_a? Hash
|
|
23
|
+
export['exec'].keys.last
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
raise "Name is missing in UX block: #{data.inspect}" unless name.present? || menu_format.present?
|
|
19
27
|
|
|
20
28
|
OpenStruct.new(
|
|
21
29
|
act: export['act'],
|
|
@@ -25,7 +33,7 @@ def parse_yaml_of_ux_block(
|
|
|
25
33
|
exec: export['exec'],
|
|
26
34
|
force: export['force'],
|
|
27
35
|
init: export['init'],
|
|
28
|
-
menu_format:
|
|
36
|
+
menu_format: menu_format,
|
|
29
37
|
name: name,
|
|
30
38
|
prompt: export['prompt'] || prompt,
|
|
31
39
|
readonly: export['readonly'].nil? ? false : export['readonly'],
|
|
@@ -47,6 +55,7 @@ module MarkdownExec
|
|
|
47
55
|
class FCB
|
|
48
56
|
def initialize(options = {})
|
|
49
57
|
@attrs = {
|
|
58
|
+
block: nil,
|
|
50
59
|
body: nil,
|
|
51
60
|
call: nil,
|
|
52
61
|
dname: nil,
|
|
@@ -66,6 +75,10 @@ module MarkdownExec
|
|
|
66
75
|
}.merge(options)
|
|
67
76
|
end
|
|
68
77
|
|
|
78
|
+
def append_block_line(line)
|
|
79
|
+
@attrs[:block].push line
|
|
80
|
+
end
|
|
81
|
+
|
|
69
82
|
def pub_name(**kwargs)
|
|
70
83
|
self.class.pub_name(@attrs, **kwargs)
|
|
71
84
|
end
|
|
@@ -388,13 +401,13 @@ module MarkdownExec
|
|
|
388
401
|
|
|
389
402
|
# calc the decoration sybol for the current block
|
|
390
403
|
def option_to_decorate_ux_block
|
|
391
|
-
symbol_or_hash = BLOCK_TYPE_COLOR_OPTIONS[@attrs[:type]]
|
|
404
|
+
symbol_or_hash = BLOCK_TYPE_COLOR_OPTIONS[@attrs[:type]] || BLOCK_TYPE_COLOR_OPTIONS[true]
|
|
392
405
|
if @attrs[:type] == BlockType::UX
|
|
393
406
|
# only UX blocks accept a symbol or a hash
|
|
394
407
|
if symbol_or_hash.is_a? Hash
|
|
395
408
|
# default to the first symbol
|
|
396
409
|
symbol = symbol_or_hash.first.last
|
|
397
|
-
symbol_or_hash.
|
|
410
|
+
symbol_or_hash.each_key do |key|
|
|
398
411
|
if key == true
|
|
399
412
|
symbol = symbol_or_hash[key]
|
|
400
413
|
break
|
|
@@ -518,6 +531,7 @@ if $PROGRAM_NAME == __FILE__
|
|
|
518
531
|
class FCBTest < Minitest::Test
|
|
519
532
|
def setup
|
|
520
533
|
@fcb_data = {
|
|
534
|
+
block: nil,
|
|
521
535
|
body: 'Sample body',
|
|
522
536
|
call: 'Sample call',
|
|
523
537
|
dname: 'Sample name',
|