markdown_exec 2.7.2 → 2.7.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf1cce75f6ae919ebb237862e74ade141e6300426e514331b4410cf7cfa0b27e
4
- data.tar.gz: 2ea6f8f6fa47f01b324b6663c6c1dcd0f69a0c2a164d7591f5c714d9618b90a4
3
+ metadata.gz: c35f2f729da73920db53053340bbe0ced75bfbb16ad59697fa6ba4016b62ae74
4
+ data.tar.gz: c20943723250feaa3e1b7218710cede9ebf4da4dd6eebf68584a805b9647b7d4
5
5
  SHA512:
6
- metadata.gz: 87b6c3f35b0fd85b06dc1d94afc6c145fd27989def6972dcaf66e85a8c899e3550376efa9b0e70efe2327e403a46615b6c51a5210653bf5bdd0e1c6946d477f7
7
- data.tar.gz: 78fd6cb33feabb7a94c0df274528cf2ffd0d4b60e1bf37328304a125b71edc44c6fd884c003af7088b0953923cee3e3a2b3f39b139b1559bf0b2b4337792ecc9
6
+ metadata.gz: 185f571fd39b4bdce955a455695413390b83c3635236871a83098bd595b184b5a79a2cd2b2778fb1fa795d658566237ed251e751fe1981a71aff192ce22da376
7
+ data.tar.gz: 19248dd05c973d9657362145826312fd2a07a7f6b4ad6834e623a19f289b35dc4d32c9c16401fc73a7e6309f4fc7ba9a5f63cc82a7db78299b623ea0d3b471f0
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.7.3] - 2025-01-29
4
+
5
+ ### Added
6
+
7
+ - Automatic loading of multiple Opts and Vars blocks when opening a document.
8
+
9
+ ### Changed
10
+
11
+ - Fix text displayed when text is wrapped to the next line.
12
+ - Handle and report failure of single tests.
13
+
14
+ ## [2.7.2] - 2025-01-03
15
+
16
+ ### Added
17
+
18
+ - Block name comparison in FCB class.
19
+ - Option for automatic shell block per document.
20
+
21
+ ### Changed
22
+
23
+ - Disable command substitution in comments.
24
+ - Fix the source reported by debug function ww0.
25
+ - Inverse the entire line to highlight the active menu line.
26
+ - Return single file if no globs in load block.
27
+ - Update the calculation and use of IDs for blocks used to retrieve the block selected from the menu.
28
+
29
+ ## [2.7.1] - 2024-12-10
30
+
31
+ ### Changed
32
+
33
+ - Register console dimensions prior to arguments.
34
+
3
35
  ## [2.7.0] - 2024-12-09
4
36
 
5
37
  ### Added
@@ -399,7 +431,7 @@ Rename options to match use.
399
431
  These blocks can be hidden blocks and required in a script.
400
432
 
401
433
  - Add a "wrap" fenced code block type to facilitate script generation.
402
- See document `examples/wrap.md`.
434
+ See document `examples/wrapped-blocks.md`.
403
435
  These blocks are hidden and can be required by one or more blocks.
404
436
 
405
437
  ### Changed
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (2.7.2)
4
+ markdown_exec (2.7.3)
5
5
  clipboard (~> 1.3.6)
6
6
  open3 (~> 0.1.1)
7
7
  optparse (~> 0.1.1)
data/Rakefile CHANGED
@@ -74,14 +74,38 @@ task :clean do
74
74
  system 'rm *.gem'
75
75
  end
76
76
 
77
+ def execute_with_error_handling(iterator)
78
+ all_error_level = 0
79
+ all_failed_files = []
80
+
81
+ iterator.each do |item|
82
+ command = yield(item)
83
+ next unless command # Skip if command is nil
84
+
85
+ result = system(command)
86
+ error_level = $?.exitstatus
87
+
88
+ if error_level != 0
89
+ puts "Error: Command '#{command}' failed with exit status #{error_level}."
90
+ all_error_level = error_level
91
+ all_failed_files << command
92
+ end
93
+ end
94
+
95
+ if all_error_level != 0
96
+ puts "Error: #{all_failed_files.join(', ')} failed."
97
+ exit all_error_level
98
+ end
99
+ end
100
+
77
101
  desc 'bats'
78
102
  task :bats do
79
- FileList['bats/**/*.bats'].each do |file|
80
- next if %w[bats/bats.bats bats/fail.bats].include?(file)
103
+ execute_with_error_handling(FileList['bats/**/*.bats']) do |file|
104
+ next nil if %w[bats/bats.bats bats/fail.bats].include?(file)
81
105
 
82
106
  # temporary clear WW to disable debugging
83
107
  # WW pollutes output expected by BATS tests
84
- system "unset WW; bats #{file}"
108
+ "unset WW; bats #{file}"
85
109
  end
86
110
  end
87
111
 
@@ -118,14 +142,8 @@ task :minitest do
118
142
  './lib/dev/process_template.rb --test'
119
143
  ]
120
144
 
121
- commands.each do |command|
122
- result = system("bundle exec ruby #{command}")
123
- error_level = $?.exitstatus
124
-
125
- if error_level != 0
126
- puts "Error: Command '#{command}' failed with exit status #{error_level}."
127
- exit error_level
128
- end
145
+ execute_with_error_handling(commands) do |command|
146
+ "bundle exec ruby #{command}"
129
147
  end
130
148
  end
131
149
  task mini: %i[minitest]
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ # Type: Opts
6
+
7
+ @test 'Opts block - before' {
8
+ skip 'Fails because command executes after the block is processed'
9
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-opts.md \
10
+ 'BEFORE Species_menu_note_format: "AFTER %{line}" '
11
+ }
12
+
13
+ @test 'Opts block - after' {
14
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-opts.md \
15
+ '[decorate-note]' \
16
+ 'AFTER Species_menu_note_format: "AFTER %{line}"'
17
+ }
18
+
19
+ @test 'Opts block - show that menu has changed' {
20
+ skip 'Unable to show that menu has changed'
21
+ spec_mde_args_expect docs/dev/block-type-opts.md '[decorate-note]' \
22
+ 'AFTER Species'
23
+ }
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ # Type: Vars
6
+
7
+ # includes output from automatic vars blocks
8
+ @test 'Vars block - auto load' {
9
+ BATS_OUTPUT_FILTER=A
10
+ spec_mde_args_expect docs/dev/block-type-vars.md show \
11
+ 'Species = Not specified Genus = Not specified Species: Not specified VAULT:'
12
+ }
13
+
14
+ # includes output from assignment and from shell block
15
+ @test 'Vars block - set variable' {
16
+ BATS_OUTPUT_FILTER=A
17
+ spec_mde_args_expect docs/dev/block-type-vars.md '[set_vault_1]' show \
18
+ 'Species = Not specified Genus = Not specified VAULT = 1 Species: Not specified VAULT: 1'
19
+ }
20
+
21
+ # handles invalid YAML in block
22
+ @test 'Vars block - invalid YAML' {
23
+ BATS_OUTPUT_FILTER=A
24
+ spec_mde_args_expect docs/dev/block-type-vars.md '[invalid_yaml]' show \
25
+ 'Species = Not specified Genus = Not specified Species: Not specified VAULT:'
26
+ }
@@ -47,26 +47,6 @@ load 'test_helper'
47
47
  run_mde_specs_md_args_expect_xansi '[VARIABLE1]' '(echo-VARIABLE1)' ' VARIABLE1: 1 VARIABLE1: 1'
48
48
  }
49
49
 
50
- # Type: Opts
51
-
52
- @test 'Opts block - before' {
53
- skip 'Fails because command executes after the block is processed'
54
- spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-opts.md \
55
- 'BEFORE Species_menu_note_format: "AFTER %{line}" '
56
- }
57
-
58
- @test 'Opts block - after' {
59
- spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-opts.md \
60
- '[decorate-note]' \
61
- 'AFTER Species_menu_note_format: "AFTER %{line}"'
62
- }
63
-
64
- @test 'Opts block - show that menu has changed' {
65
- skip 'Unable to show that menu has changed'
66
- spec_mde_args_expect docs/dev/block-type-opts.md '[decorate-note]' \
67
- 'AFTER Species'
68
- }
69
-
70
50
  # Type: Port
71
51
 
72
52
  # includes output from assignment and from shell block
@@ -81,19 +61,3 @@ load 'test_helper'
81
61
  spec_mde_args_expect docs/dev/block-type-port.md VAULT-is-export show \
82
62
  ' VAULT: This variable has not been set.'
83
63
  }
84
-
85
- # Type: Vars
86
-
87
- # includes output from automatic vars block
88
- @test 'Vars block - auto load' {
89
- BATS_OUTPUT_FILTER=A
90
- spec_mde_args_expect docs/dev/block-type-vars.md show \
91
- 'Species = Not specified Species: Not specified VAULT:'
92
- }
93
-
94
- # includes output from assignment and from shell block
95
- @test 'Vars block - set variable' {
96
- BATS_OUTPUT_FILTER=A
97
- spec_mde_args_expect docs/dev/block-type-vars.md '[set_vault_1]' show \
98
- 'Species = Not specified VAULT = 1 Species: Not specified VAULT: 1'
99
- }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'Text and Headings' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/line-wrapping.md \
7
+ " DEMO WRAPPING LONG LINES__MDE detects the screen's dimensions:_height (lines) and width (characters)__Normal document text is displayed as_disabled menu lines. The width of these_lines is limited according to the screen's_width.__Test Indented Lines__ Indented with two spaces, this line_ should wrap in an aesthetically pleasing_ way.__ Indented with a tab, this line should_ wrap in an aesthetically pleasing way.__ SPECIES GENUS FAMILY ORDER CLASS PHYLUM_ KINGDOM DOMAIN_species genus family order class phylum_kingdom domain"
8
+ }
@@ -13,7 +13,7 @@ __filedirs_all()
13
13
  }
14
14
 
15
15
  _mde_echo_version() {
16
- echo "2.7.2"
16
+ echo "2.7.3"
17
17
  }
18
18
 
19
19
  _mde() {
@@ -6,6 +6,9 @@ menu_note_format: "AFTER %{line}"
6
6
  ```opts :(document_opts)
7
7
  menu_final_divider:
8
8
  menu_for_saved_lines: false
9
+ ```
10
+ / Demonstrate multiple (document_opts) in a single file
11
+ ```opts :(document_opts)
9
12
  menu_initial_divider:
10
13
  menu_note_format: "BEFORE %{line}"
11
- ```
14
+ ```
@@ -1,6 +1,15 @@
1
+ ```vars :(document_vars)
2
+ Species: Not specified
3
+ ```
4
+ ```vars :(document_vars)
5
+ Genus: Not specified
6
+ ```
1
7
  ```vars :[set_vault_1]
2
8
  VAULT: 1
3
9
  ```
10
+ ```vars :[invalid_yaml]
11
+ this is not yaml
12
+ ```
4
13
  ```bash :show
5
14
  echo "Species: $Species"
6
15
  echo "VAULT: $VAULT"
@@ -8,8 +17,6 @@ echo "VAULT: $VAULT"
8
17
  | Variable| Value
9
18
  | -| -
10
19
  | Species| ${Species}
20
+ | Genus| ${Genus}
11
21
  | VAULT| ${VAULT}
12
- @import bats-document-configuration.md
13
- ```vars :(document_vars)
14
- Species: Not specified
15
- ```
22
+ @import bats-document-configuration.md
@@ -0,0 +1,24 @@
1
+ # Demo wrapping long lines
2
+
3
+ MDE detects the screen's dimensions: height (lines) and width (characters)
4
+
5
+ Normal document text is displayed as disabled menu lines. The width of these lines is limited according to the screen's width.
6
+
7
+ ::: Test Indented Lines
8
+
9
+ Indented with two spaces, this line should wrap in an aesthetically pleasing way.
10
+
11
+ Indented with a tab, this line should wrap in an aesthetically pleasing way.
12
+
13
+ # species genus family order class phylum kingdom domain
14
+ ## species genus family order class phylum kingdom domain
15
+ @import bats-document-configuration.md
16
+ ```opts :(document_opts)
17
+ divider4_center: false
18
+ heading1_center: true
19
+ heading2_center: false
20
+ screen_width: 48
21
+
22
+ menu_note_match: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
23
+
24
+ ```
@@ -1,59 +1,87 @@
1
- # Demonstrate link blocks set variables
2
- @import example-document-opts.md
3
- ```opts :(document_opts)
4
- execute_in_own_window: false
5
- menu_with_inherited_lines: true
6
- output_execution_report: false
7
- output_execution_summary: false
8
- pause_after_script_execution: true
1
+ # Demonstrate Setting Variables in the Inherited Lines
2
+
3
+ ```link :select-a-folder +(select-a-folder)
4
+ eval: true
5
+ ```
6
+ ```bash :(select-a-folder)
7
+ echo "PT=$(osascript -e 'do shell script "echo " & quoted form of POSIX path of (choose folder with prompt "Please select a folder:")' 2>/dev/null)"
9
8
  ```
10
9
 
11
- ## Demonstrate a link block that sets a variable
12
- ::: Select below to trigger. If it prints "VARIABLE1: 1", the Link block was processed.
10
+ This table displays the value of variables in the context of the current inherited lines. At first, the variable is empty unless it exists in the current shell environment.
13
11
 
14
12
  | Variable| Value
15
13
  | -| -
16
- | VARIABLE1| ${VARIABLE1}
14
+ | SPECIES| ${SPECIES}
15
+
16
+ ## Current Inherited Lines
17
+
18
+ ```view
19
+ View the current inherited lines.
20
+ ```
21
+
22
+ The inherited lines can also be displayed automatically within the menu by enabling this option:
23
+
24
+ ```opts
25
+ menu_with_inherited_lines: true
26
+ ```
27
+
28
+ ## Setting Variables in the Inherited Lines
29
+
30
+ You can set environment variables in the inherited lines by adding shell expressions. For example, a line such as `SPECIES=Unknown` in the inherited lines defines a variable that can be used in the rest of the executed script.
31
+
32
+ Below are several ways to add such expressions to the inherited lines:
33
+
34
+ ### Vars Block
35
+
36
+ This block (YAML) adds a variable and its value to the inherited lines:
37
+
38
+ ```vars
39
+ SPECIES: Tapanuli Orangutan
40
+ ```
41
+
42
+ ### Link Block
43
+
44
+ This block (YAML) also adds a variable and its value to the inherited lines:
17
45
 
18
- The block sets VARIABLE1.
19
- For each environment variable in `vars`, append an inherited line that assigns the variable the specified value.
20
46
  ```link
21
47
  vars:
22
- VARIABLE1: 1
48
+ SPECIES: Psychedelic Frogfish
23
49
  ```
24
50
 
25
- ## Demonstrate a link block that requires a shell block that sets a variable
26
- This block "[bash_set_to_3]" is required below. It sets the variable "ALPHA".
27
- ```bash :[bash_set_to_3]
28
- ALPHA=3
29
- ```
30
- ::: Select below to trigger. If it prints "ALPHA: 3", the Link block was processed.
31
- These blocks require the *code* of the named shell block.
32
- ```link +[bash_set_to_3]
33
- block: "(display_variable_ALPHA)"
34
- ```
35
- ```link +[bash_set_to_3]
36
- next_block: "(display_variable_ALPHA)"
37
- ```
51
+ ### Link+Bash Blocks
38
52
 
39
- This block "[bash_set_to_4]" is required below. It prints a command that sets the variable "ALPHA".
40
- ```bash :[bash_set_to_4]
41
- echo "ALPHA=4"
42
- ```
43
- ::: Select below to trigger. If it prints "ALPHA: 4", the Link block was processed.
44
- These blocks require the *output* of the execution of the code in the named shell block.
45
- ```link +[bash_set_to_4]
46
- eval: true
47
- block: "(display_variable_ALPHA)"
53
+ ::: Adding Code to the Inherited Lines
54
+
55
+ This Link block (YAML) appends the Bash code defined in the referenced block to the inherited lines:
56
+
57
+ ```link :add-bash-code +[bash_species]
48
58
  ```
49
- ```link +[bash_set_to_4]
59
+ ```bash :[bash_species] @disable
60
+ SPECIES='Ruby Seadragon'
61
+ ```
62
+
63
+ If necessary to extract environment variable values displayed in the menu, inherited lines are executed every time the menu displayed. Therefore, do add code that has unwanted side effects when executed multiple times.
64
+
65
+ ::: Adding Evaluated Code Output to the Inherited Lines
66
+
67
+ This Link block (YAML) appends the output of the Bash code to the inherited lines. The Bash code is executed first to generate the output:
68
+
69
+ ```link :add-evaluated-bash-code +[bash_species_code]
50
70
  eval: true
51
- next_block: "(display_variable_ALPHA)"
52
71
  ```
72
+ ```bash :[bash_species_code] @disable
73
+ echo "SPECIES='Illacme tobini (Millipede)'"
74
+ ```
53
75
 
54
76
  | Variable| Value
55
77
  | -| -
56
- | ALPHA| ${ALPHA}
78
+ | SPECIES| ${SPECIES}
57
79
 
58
- ```bash :(display_variable_ALPHA)
59
- ```
80
+ @import example-document-opts.md
81
+ ```opts :(document_opts)
82
+ execute_in_own_window: false
83
+ menu_with_inherited_lines: false
84
+ output_execution_report: false
85
+ output_execution_summary: false
86
+ pause_after_script_execution: true
87
+ ```
data/lib/colorize.rb CHANGED
@@ -13,23 +13,15 @@ class String
13
13
  # @return [String] The formatted string.
14
14
  def method_missing(method_name, *args, &block)
15
15
  case method_name.to_s
16
- # when /^bg_rgb_/
17
- # bytes = $'.split('_')
18
- # bg_rgb_color(bytes[0..2].join(';'))
19
16
  when /^fg_bg_rgb_/
20
- pp [__LINE__, caller[0]]; binding.irb
21
17
  bytes = $'.split('_')
22
18
  fg_bg_rgb_color(bytes[0..2].join(';'), bytes[3..5].join(';'))
23
19
  when /^fg_bg_rgbh_/
24
- pp [__LINE__, caller[0]]; binding.irb
25
20
  hex_to_fg_bg_rgb($')
26
21
  when /^fg_rgb_/
27
- pp [__LINE__, caller[0]]; binding.irb
28
22
  fg_rgb_color($'.gsub('_', ';'))
29
23
  when /^fg_rgbh_/
30
- pp [__LINE__, caller[0]]; binding.irb
31
24
  hex_to_rgb($')
32
-
33
25
  when 'to_a', 'to_ary', 'to_hash', 'to_int', 'to_io', 'to_regexp'
34
26
  nil
35
27
  else
@@ -41,24 +33,14 @@ class String
41
33
  #
42
34
  # @return [String] The string wrapped in an ANSI control sequence.
43
35
  def ansi_control_sequence
44
- pp [__LINE__, caller[0]]; binding.irb
45
36
  "\033[#{self}\033[0m"
46
37
  end
47
38
 
48
- # # Applies a 24-bit RGB background color to the string.
49
- # #
50
- # # @param rgb [String] The RGB color, expressed as a string like "1;2;3".
51
- # # @return [String] The string with the applied RGB foreground color.
52
- # def bg_rgb_color(rgb)
53
- # "48;2;#{rgb}m#{self}".ansi_control_sequence
54
- # end
55
-
56
39
  # Applies a 24-bit RGB foreground color to the string.
57
40
  #
58
41
  # @param rgb [String] The RGB color, expressed as a string like "1;2;3".
59
42
  # @return [String] The string with the applied RGB foreground color.
60
43
  def fg_bg_rgb_color(fg_rgb, bg_rgb)
61
- pp [__LINE__, caller[0]]; binding.irb
62
44
  "38;2;#{fg_rgb}m\033[48;2;#{bg_rgb}m#{self}".ansi_control_sequence
63
45
  end
64
46
 
@@ -67,7 +49,6 @@ class String
67
49
  # @param rgb [String] The RGB color, expressed as a string like "1;2;3".
68
50
  # @return [String] The string with the applied RGB foreground color.
69
51
  def fg_rgb_color(rgb)
70
- pp [__LINE__, caller[0]]; binding.irb
71
52
  "38;2;#{rgb}m#{self}".ansi_control_sequence
72
53
  end
73
54
 
@@ -76,7 +57,6 @@ class String
76
57
  # @param hex_str [String] The RGB color, expressed as a hex string like "FF00FF".
77
58
  # @return [String] The string with the applied RGB foreground color.
78
59
  def hex_to_fg_bg_rgb(hex_str)
79
- pp [__LINE__, caller[0]]; binding.irb
80
60
  values = hex_str.split('_').map { |hex| hex.to_i(16).to_s }
81
61
  fg_bg_rgb_color(
82
62
  values[0..2].join(';'),
@@ -89,7 +69,6 @@ class String
89
69
  # @param hex_str [String] The RGB color, expressed as a hex string like "FF00FF".
90
70
  # @return [String] The string with the applied RGB foreground color.
91
71
  def hex_to_rgb(hex_str)
92
- pp [__LINE__, caller[0]]; binding.irb
93
72
  fg_rgb_color(
94
73
  hex_str.split('_').map { |hex| hex.to_i(16).to_s }.join(';')
95
74
  )
@@ -99,7 +78,6 @@ class String
99
78
  #
100
79
  # @return [String] The original string.
101
80
  def plain
102
- pp [__LINE__, caller[0]]; binding.irb
103
81
  self
104
82
  end
105
83
 
@@ -126,20 +104,16 @@ class String
126
104
  def violet; fg_rgbh_94_00_D3; end
127
105
  def yellow; fg_rgbh_FF_FF_00; end
128
106
 
129
- def x
130
- pp [__LINE__, caller[1]]; binding.irb
131
- end
132
-
133
107
  # graphics modes
134
- def bold; x; "\033[1m#{self}\033[22m"; end
135
- def bold_italic; x; "\033[1m\033[3m#{self}\033[22m\033[23m"; end
136
- def bold_underline; x; "\033[1m\033[4m#{self}\033[22m\033[24m"; end
137
- def dim; x; "\033[2m#{self}\033[22m"; end
138
- def italic; x; "\033[3m#{self}\033[23m"; end
139
- def underline; x; "\033[4m#{self}\033[24m"; end
140
- def underline_italic; x; "\033[4m\033[3m#{self}\033[23m\033[24m"; end
141
- def blinking; x; "\033[5m#{self}\033[25m"; end
142
- def inverse; x; "\033[7m#{self}\033[27m"; end
143
- def hidden; x; "\033[8m#{self}\033[28m"; end
144
- def strikethrough; x; "\033[9m#{self}\033[29m"; end
108
+ def bold; "\033[1m#{self}\033[22m"; end
109
+ def bold_italic; "\033[1m\033[3m#{self}\033[22m\033[23m"; end
110
+ def bold_underline; "\033[1m\033[4m#{self}\033[22m\033[24m"; end
111
+ def dim; "\033[2m#{self}\033[22m"; end
112
+ def italic; "\033[3m#{self}\033[23m"; end
113
+ def underline; "\033[4m#{self}\033[24m"; end
114
+ def underline_italic; "\033[4m\033[3m#{self}\033[23m\033[24m"; end
115
+ def blinking; "\033[5m#{self}\033[25m"; end
116
+ def inverse; "\033[7m#{self}\033[27m"; end
117
+ def hidden; "\033[8m#{self}\033[28m"; end
118
+ def strikethrough; "\033[9m#{self}\033[29m"; end
145
119
  end
data/lib/format_table.rb CHANGED
@@ -188,7 +188,6 @@ end
188
188
  return if $PROGRAM_NAME != __FILE__
189
189
 
190
190
  require 'minitest/autorun'
191
- require_relative 'colorize'
192
191
 
193
192
  class TestMarkdownTableFormatter < Minitest::Test
194
193
  def setup
@@ -91,6 +91,10 @@ module HashDelegatorSelf
91
91
  blocks.find { |item| item.send(msg) == value } || default
92
92
  end
93
93
 
94
+ def block_select(blocks, msg, value, default = nil)
95
+ blocks.select { |item| item.send(msg) == value }
96
+ end
97
+
94
98
  def code_merge(*bodies)
95
99
  merge_lists(*bodies)
96
100
  end
@@ -979,16 +983,19 @@ module MarkdownExec
979
983
 
980
984
  # sets ENV
981
985
  def code_from_vars_block_to_set_environment_variables(selected)
982
- code_lines = []
983
- YAML.load(selected.body.join("\n"))&.each do |key, value|
984
- ENV[key] = value.to_s
985
- code_lines.push "#{key}=#{Shellwords.escape(value)}"
986
+ code_lines = []
987
+ case data = YAML.load(selected.body.join("\n"))
988
+ when Hash
989
+ data.each do |key, value|
990
+ ENV[key] = value.to_s
991
+ code_lines.push "#{key}=#{Shellwords.escape(value)}"
986
992
 
987
- next unless @delegate_object[:menu_vars_set_format].present?
993
+ next unless @delegate_object[:menu_vars_set_format].present?
988
994
 
989
- formatted_string = format(@delegate_object[:menu_vars_set_format],
990
- { key: key, value: value })
991
- print string_send_color(formatted_string, :menu_vars_set_color)
995
+ formatted_string = format(@delegate_object[:menu_vars_set_format],
996
+ { key: key, value: value })
997
+ print string_send_color(formatted_string, :menu_vars_set_color)
998
+ end
992
999
  end
993
1000
  code_lines
994
1001
  end
@@ -1232,11 +1239,12 @@ module MarkdownExec
1232
1239
  wrap: nil,
1233
1240
  fcb: nil
1234
1241
  )
1235
- line_cap = NamedCaptureExtractor.extract_named_group2(match_data)
1242
+ ww 'match_data', match_data
1243
+ line_cap = NamedCaptureExtractor.extract_named_group_match_data(match_data)
1236
1244
  # replace tabs in indent
1237
1245
  line_cap[:indent] ||= ''
1238
1246
  line_cap[:indent] = line_cap[:indent].dup if line_cap[:indent].frozen?
1239
- line_cap[:indent].gsub!("\t", ' ')
1247
+ line_cap[:indent].gsub!("\t", ' ') # TAB_SIZE = 4
1240
1248
  # replace tabs in text
1241
1249
  line_cap[:text] ||= ''
1242
1250
  line_cap[:text] = line_cap[:text].dup if line_cap[:text].frozen?
@@ -1264,6 +1272,7 @@ module MarkdownExec
1264
1272
  end
1265
1273
  end
1266
1274
 
1275
+ use_fcb = !fcb.nil? # fcb only for the first record if any
1267
1276
  line_caps.each_with_index do |line_obj, index|
1268
1277
  next if line_obj[:text].nil?
1269
1278
 
@@ -1287,7 +1296,7 @@ module MarkdownExec
1287
1296
 
1288
1297
  line_obj[:line] = line_obj[:indent] + line_obj[:text]
1289
1298
 
1290
- if fcb.nil?
1299
+ if !use_fcb
1291
1300
  fcb = FCB.new(
1292
1301
  center: center,
1293
1302
  chrome: true,
@@ -1321,6 +1330,7 @@ module MarkdownExec
1321
1330
  fcb.oname = line_obj[:text]
1322
1331
  fcb.text = line_obj[:text]
1323
1332
  fcb.type = type
1333
+ use_fcb = false # next line is new record
1324
1334
  end
1325
1335
 
1326
1336
  blocks.push fcb
@@ -1956,7 +1966,7 @@ module MarkdownExec
1956
1966
  [exit_prompt] + dirs.sort.map do |file|
1957
1967
  { name: format(
1958
1968
  block_data['view'] || view,
1959
- NamedCaptureExtractor.extract_named_group2(
1969
+ NamedCaptureExtractor.extract_named_group_match_data(
1960
1970
  file.match(
1961
1971
  Regexp.new(block_data['filename_pattern'] ||
1962
1972
  filename_pattern)
@@ -2240,7 +2250,6 @@ module MarkdownExec
2240
2250
  key_format: '${%s}',
2241
2251
  pattern: nil
2242
2252
  )
2243
- # defined($x) ? '' : ($x = 1; pp [__LINE__, caller.deref])
2244
2253
  pattern ||= options_variable_expression_regexp
2245
2254
  return if pattern.nil?
2246
2255
 
@@ -2553,20 +2562,29 @@ module MarkdownExec
2553
2562
  label_format_above = @delegate_object[:shell_code_label_format_above]
2554
2563
  label_format_below = @delegate_object[:shell_code_label_format_below]
2555
2564
 
2556
- [label_format_above.present? &&
2557
- format(label_format_above,
2558
- block_source.merge({ block_name: selected.pub_name }))] +
2559
- output_lines.map do |line|
2560
- re = Regexp.new(link_block_data.fetch('pattern', '(?<line>.*)'))
2561
- next unless re =~ line
2562
-
2563
- re.gsub_format(line,
2564
- link_block_data.fetch('format',
2565
- '%{line}'))
2566
- end.compact +
2567
- [label_format_below.present? &&
2568
- format(label_format_below,
2569
- block_source.merge({ block_name: selected.pub_name }))]
2565
+ ([
2566
+ label_format_above.present? ?
2567
+ format(
2568
+ label_format_above,
2569
+ block_source.merge({ block_name: selected.pub_name })
2570
+ ) : nil
2571
+ ] +
2572
+ output_lines.map do |line|
2573
+ re = Regexp.new(link_block_data.fetch('pattern', '(?<line>.*)'))
2574
+ next unless re =~ line
2575
+
2576
+ re.gsub_format(
2577
+ line,
2578
+ link_block_data.fetch('format', '%{line}')
2579
+ )
2580
+ end +
2581
+ [
2582
+ label_format_below.present? ?
2583
+ format(
2584
+ label_format_below,
2585
+ block_source.merge({ block_name: selected.pub_name })
2586
+ ) : nil
2587
+ ]).compact
2570
2588
  end
2571
2589
 
2572
2590
  def link_history_push_and_next(
@@ -2641,43 +2659,23 @@ module MarkdownExec
2641
2659
  return
2642
2660
  end
2643
2661
 
2644
- block = HashDelegator.block_find(all_blocks, :oname, block_name)
2645
- return unless block
2662
+ blocks = HashDelegator.block_select(all_blocks, :oname, block_name)
2663
+ return if blocks.empty?
2646
2664
 
2647
- options_state = read_show_options_and_trigger_reuse(
2648
- mdoc: mdoc,
2649
- selected: block
2665
+ update_menu_base(
2666
+ blocks.each.with_object({}) do |block, merged_options|
2667
+ options_state = read_show_options_and_trigger_reuse(
2668
+ mdoc: mdoc,
2669
+ selected: block
2670
+ )
2671
+ merged_options.merge!(options_state.options)
2672
+ end
2650
2673
  )
2651
- update_menu_base(options_state.options)
2652
2674
 
2653
2675
  @opts_most_recent_filename = @delegate_object[:filename]
2654
2676
  true
2655
2677
  end
2656
2678
 
2657
- def load_document_shell_block(all_blocks, mdoc: nil)
2658
- block_name = @delegate_object[:document_load_shell_block_name]
2659
- unless block_name.present? &&
2660
- @shell_most_recent_filename != @delegate_object[:filename]
2661
- return
2662
- end
2663
-
2664
- fcb = HashDelegator.block_find(all_blocks, :oname, block_name)
2665
- return unless fcb
2666
-
2667
- @shell_most_recent_filename = @delegate_object[:filename]
2668
-
2669
- if mdoc
2670
- mdoc.collect_recursively_required_code(
2671
- anyname: fcb.pub_name,
2672
- label_format_above: @delegate_object[:shell_code_label_format_above],
2673
- label_format_below: @delegate_object[:shell_code_label_format_below],
2674
- block_source: block_source
2675
- )[:code]
2676
- else
2677
- fcb.body
2678
- end
2679
- end
2680
-
2681
2679
  def load_auto_vars_block(all_blocks,
2682
2680
  block_name: @delegate_object[:document_load_vars_block_name])
2683
2681
  unless block_name.present? &&
@@ -2685,11 +2683,16 @@ module MarkdownExec
2685
2683
  return
2686
2684
  end
2687
2685
 
2688
- block = HashDelegator.block_find(all_blocks, :oname, block_name)
2689
- return unless block
2686
+ blocks = HashDelegator.block_select(all_blocks, :oname, block_name)
2687
+ return if blocks.empty?
2690
2688
 
2691
2689
  @vars_most_recent_filename = @delegate_object[:filename]
2692
- code_from_vars_block_to_set_environment_variables(block)
2690
+
2691
+ (blocks.each.with_object([]) do |block, merged_options|
2692
+ merged_options.push(
2693
+ code_from_vars_block_to_set_environment_variables(block)
2694
+ )
2695
+ end).to_a
2693
2696
  end
2694
2697
 
2695
2698
  def load_cli_or_user_selected_block(all_blocks: [], menu_blocks: [],
@@ -2712,6 +2715,30 @@ module MarkdownExec
2712
2715
  SelectedBlockMenuState.new(block, source, state)
2713
2716
  end
2714
2717
 
2718
+ def load_document_shell_block(all_blocks, mdoc: nil)
2719
+ block_name = @delegate_object[:document_load_shell_block_name]
2720
+ unless block_name.present? &&
2721
+ @shell_most_recent_filename != @delegate_object[:filename]
2722
+ return
2723
+ end
2724
+
2725
+ fcb = HashDelegator.block_find(all_blocks, :oname, block_name)
2726
+ return unless fcb
2727
+
2728
+ @shell_most_recent_filename = @delegate_object[:filename]
2729
+
2730
+ if mdoc
2731
+ mdoc.collect_recursively_required_code(
2732
+ anyname: fcb.pub_name,
2733
+ label_format_above: @delegate_object[:shell_code_label_format_above],
2734
+ label_format_below: @delegate_object[:shell_code_label_format_below],
2735
+ block_source: block_source
2736
+ )[:code]
2737
+ else
2738
+ fcb.body
2739
+ end
2740
+ end
2741
+
2715
2742
  # format + glob + select for file in load block
2716
2743
  # name has references to ENV vars and doc and batch vars
2717
2744
  # incl. timestamp
@@ -3839,10 +3866,10 @@ module MarkdownExec
3839
3866
  shell: fcb_title_groups.fetch(:shell, ''),
3840
3867
  start_line: line,
3841
3868
  stdin: if (tn = rest.match(/<(?<type>\$)?(?<name>[A-Za-z_-]\S+)/))
3842
- NamedCaptureExtractor.extract_named_group2(tn)
3869
+ NamedCaptureExtractor.extract_named_group_match_data(tn)
3843
3870
  end,
3844
3871
  stdout: if (tn = rest.match(/>(?<type>\$)?(?<name>[\w.\-]+)/))
3845
- NamedCaptureExtractor.extract_named_group2(tn)
3872
+ NamedCaptureExtractor.extract_named_group_match_data(tn)
3846
3873
  end,
3847
3874
  title: title,
3848
3875
  type: fcb_title_groups.fetch(:type, ''),
@@ -7,5 +7,5 @@ module MarkdownExec
7
7
  BIN_NAME = 'mde'
8
8
  GEM_NAME = 'markdown_exec'
9
9
  TAP_DEBUG = 'MDE_DEBUG'
10
- VERSION = '2.7.2'
10
+ VERSION = '2.7.3'
11
11
  end
data/lib/markdown_exec.rb CHANGED
@@ -19,7 +19,6 @@ require_relative 'ansi_formatter'
19
19
  require_relative 'cached_nested_file_reader'
20
20
  require_relative 'cli'
21
21
  require_relative 'color_scheme'
22
- require_relative 'colorize'
23
22
  require_relative 'directory_searcher'
24
23
  require_relative 'env'
25
24
  require_relative 'exceptions'
@@ -95,7 +94,7 @@ class NamedCaptureExtractor
95
94
  str&.match(regexp)&.named_captures&.transform_keys(&:to_sym)
96
95
  end
97
96
 
98
- def self.extract_named_group2(match_data)
97
+ def self.extract_named_group_match_data(match_data)
99
98
  match_data&.named_captures&.transform_keys(&:to_sym)
100
99
  end
101
100
  end
data/lib/menu.src.yml CHANGED
@@ -904,11 +904,10 @@
904
904
  :procname: val_as_str
905
905
 
906
906
  ## lines that start with "/" are comments (hidden), not notes (visible)
907
- # - :default: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
908
907
  - :opt_name: menu_note_match
909
908
  :env_var: MDE_MENU_NOTE_MATCH
910
909
  :description: Pattern for notes in block selection menu
911
- :default: "^(?<line>(?![ \t]*/)(?<text>.*?)(?<trailing>[ \t]*))$"
910
+ :default: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
912
911
  :procname: val_as_str
913
912
 
914
913
  - :opt_name: menu_option_back_name
data/lib/menu.yml CHANGED
@@ -766,7 +766,7 @@
766
766
  - :opt_name: menu_note_match
767
767
  :env_var: MDE_MENU_NOTE_MATCH
768
768
  :description: Pattern for notes in block selection menu
769
- :default: "^(?<line>(?![ \t]*/)(?<text>.*?)(?<trailing>[ \t]*))$"
769
+ :default: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
770
770
  :procname: val_as_str
771
771
  - :opt_name: menu_option_back_name
772
772
  :env_var: MDE_MENU_OPTION_BACK_NAME
data/lib/ww.rb CHANGED
@@ -15,7 +15,7 @@ if $debug && ENV['WW_MINIMUM'].nil?
15
15
  end
16
16
 
17
17
  def ww(*objs, **kwargs)
18
- return unless $debug
18
+ return objs.size == 1 ? objs.first : objs unless $debug
19
19
 
20
20
  ww0(*objs, **kwargs.merge(locations: caller_locations))
21
21
  end
@@ -24,7 +24,7 @@ def ww0(*objs,
24
24
  category: nil,
25
25
  full_backtrace: false,
26
26
  level: :debug,
27
- locations: caller_locations[1..-1],
27
+ locations: caller_locations,
28
28
  log_file: nil,
29
29
  output: $stderr,
30
30
  single_line: false,
@@ -70,11 +70,13 @@ def ww0(*objs,
70
70
  output.flush
71
71
 
72
72
  # Optionally log to a file
73
- return unless log_file
73
+ return objs.size == 1 ? objs.first : objs unless log_file
74
74
 
75
75
  File.open(log_file, 'a') do |file|
76
76
  file.puts(formatted_message)
77
77
  end
78
+
79
+ objs.size == 1 ? objs.first : objs
78
80
  end
79
81
 
80
82
  class Array
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.7.2
4
+ version: 2.7.3
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-01-10 00:00:00.000000000 Z
11
+ date: 2025-01-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -107,6 +107,8 @@ files:
107
107
  - assets/select_a_block.png
108
108
  - assets/select_a_file.png
109
109
  - bats/bats.bats
110
+ - bats/block-type-opts.bats
111
+ - bats/block-type-vars.bats
110
112
  - bats/block-types.bats
111
113
  - bats/border.bats
112
114
  - bats/cli.bats
@@ -115,6 +117,7 @@ files:
115
117
  - bats/fail.bats
116
118
  - bats/history.bats
117
119
  - bats/import.bats
120
+ - bats/line-wrapping.bats
118
121
  - bats/markup.bats
119
122
  - bats/mde.bats
120
123
  - bats/options-collapse.bats
@@ -143,6 +146,7 @@ files:
143
146
  - docs/dev/document-shell.md
144
147
  - docs/dev/import-missing.md
145
148
  - docs/dev/import.md
149
+ - docs/dev/line-wrapping.md
146
150
  - docs/dev/linked-file.md
147
151
  - docs/dev/load1.sh
148
152
  - docs/dev/load_code.md
@@ -201,7 +205,7 @@ files:
201
205
  - examples/variable-expansion-save-block.md
202
206
  - examples/variable-expansion.md
203
207
  - examples/vars-blocks.md
204
- - examples/wrap.md
208
+ - examples/wrapped-blocks.md
205
209
  - lib/ansi_formatter.rb
206
210
  - lib/ansi_string.rb
207
211
  - lib/argument_processor.rb
File without changes