markdown_exec 2.8.1 → 2.8.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d752af0db5e1c1a770b64f9341c3d08e1e9bc8612230a9cb44ddc7fddc4c3051
4
- data.tar.gz: 5ba8524b3323bd8333b82a5d0607fbb9db59a5157a1c7ae0564b3f624f26addd
3
+ metadata.gz: dfa1920cdbee40306492b597411dff701777c0ac158dc969a02d3ac2db7351b2
4
+ data.tar.gz: fe5c8229410f4263b9aa394c99f1d1be61b6a119684ca5c29e8f0a7851d4391a
5
5
  SHA512:
6
- metadata.gz: 29b210e56b46a1edf099c02267e2b3c7cdae6701f7ee99d5a946d06eea7272da3534765110ec36a6de017a10d0f4833c9075c27dacb0cec8b050192d3892d748
7
- data.tar.gz: e73cd906ce9035c8c78d2e301866af4a76bc7a730c5109fc8cc59ecf64679cb578fb04b324e700df064886d250c394c441f77850b9e21230d346d08bd92a9a5f
6
+ metadata.gz: e2566c1f28e9eb898c490aa9076d762fe76b8f2092a1b6b4a9d37ff889d02bea021cf84fad63c2f9598d7ba17d7a6ac63840d49958d6dfad9f45b57250a4d3b7
7
+ data.tar.gz: 44a40a84a65eb477951b6929307837cc8493e70b9fe76b5065bb86e54b2b10f07241de175552132979ddb00b5c8bdce031d64688189b78f5da9f953e74399f4a
data/.rubocop.yml CHANGED
@@ -76,6 +76,9 @@ Security/YAMLLoad:
76
76
  Style/ClassVars:
77
77
  Enabled: false
78
78
 
79
+ Style/CombinableLoops:
80
+ Enabled: false
81
+
79
82
  Style/CommentedKeyword:
80
83
  Enabled: false
81
84
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,58 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.8.3] - 2025-02-27
4
+
5
+ ### Added
6
+
7
+ - "echo" support to UX blocks for evaluated shell expressions
8
+
9
+ Introduces the `echo` key to UX blocks, allowing the output of an
10
+ evaluated shell expression to be assigned to a named variable.
11
+ Implements `export_echo_with_code` to execute the expression safely
12
+ and handle invalidated outputs. Also ensures proper transformation of
13
+ export values.
14
+
15
+ - Persist allocated FCBs.
16
+
17
+ - Read-only flag to UX menu blocks
18
+
19
+ Introduces a `readonly` flag for UX menu blocks, allowing exports to
20
+ specify whether a block should be immutable. The flag is assigned from
21
+ the export definition and enforced in the menu logic.
22
+
23
+ ### Changed
24
+
25
+ - Correct indent of all lines displayed for a block.
26
+ - Retain whitespace in output from shell blocks.
27
+ - Remove a function to report the compiled version from the tab completion script. It is not used.
28
+
29
+ ## [2.8.2] - 2025-02-19
30
+
31
+ ### Added
32
+
33
+ - UX blocks can add preconditions. Preconditions are variable names that must be set before the UX block is executed. If any preconditions are not set, a warning is displayed, and the sequence is aborted.
34
+ - UX blocks can require shell an other UX blocks.
35
+ - UX blocks are evaluated in order and calculation can depend on prior variables in the same sequence.
36
+
37
+ ### Changed
38
+
39
+ - Hide all blocks per their initial title instead of `oname`.
40
+ - Make menu blocks for list of files found to fix crash.
41
+ - Use a block ID to recall the selected block.
42
+ - UX blocks are hidden similar to the rest.
43
+
44
+ ## [2.8.1] - 2025-02-13
45
+
46
+ ### Added
47
+
48
+ - BATS tests for UX block type.
49
+
50
+ ### Changed
51
+
52
+ - Improve persistence of position in menu on reload
53
+ - Update block-type-ux-exec BATS test.
54
+ - Refactor menu for selecting items with facets.
55
+
3
56
  ## [2.8.0] - 2025-02-10
4
57
 
5
58
  ### Added
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (2.8.1)
4
+ markdown_exec (2.8.3)
5
5
  clipboard (~> 1.3.6)
6
6
  open3 (~> 0.1.1)
7
7
  optparse (~> 0.1.1)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'hide blocks' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-hide.md \
7
+ 'visible'
8
+ }
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'automatic block - default' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-echo.md \
7
+ 'VAR=markdown_exec_IAB='
8
+ }
9
+
10
+ @test 'inherited lines' {
11
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-echo.md \
12
+ '(menu_with_inherited_lines)' \
13
+ 'VAR=markdown_exec_VAR=markdown_exec_IAB='
14
+ }
15
+
16
+ @test 'selected block' {
17
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-echo.md \
18
+ '(VAR_has_count)' '[IAB_has_count]' \
19
+ 'VAR=14_IAB=1414'
20
+ }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'An undefined variable is a precondition' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-preconditions.md \
7
+ 'A value must exist for: MISSING_VARIABLE_SPECIES='
8
+ }
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'automatic block - disabled' {
6
+ spec_mde_args_expect \
7
+ docs/dev/block-type-ux-readonly.md \
8
+ --list-blocks-message readonly --list-blocks-type 3 --list-blocks \
9
+ true
10
+ }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'Output of executed commands as initial value' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-require.md \
7
+ 'SPECIES=Pongo tapanuliensis_GENUS=Pongo_NAME=Pongo tapanuliensis - Pongo_NAME2=Pongo tapanuliensis - Pongo'
8
+ }
@@ -7,8 +7,8 @@ load 'test_helper'
7
7
  # includes output from automatic vars blocks
8
8
  @test 'Vars block - auto load' {
9
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:'
10
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-vars.md show \
11
+ 'Species = Not specified_Genus = Not specified__Species: Not specified_VAULT: '
12
12
  }
13
13
 
14
14
  # includes output from assignment and from shell block
@@ -22,5 +22,5 @@ load 'test_helper'
22
22
  @test 'Vars block - invalid YAML' {
23
23
  BATS_OUTPUT_FILTER=A
24
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:'
25
+ 'Species = Not specified Genus = Not specified Species: Not specified VAULT: '
26
26
  }
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'Retain whitespace in output from shell blocks' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/indented-multi-line-output.md \
7
+ '[make-output]' \
8
+ '_Species_ Genus_ Family_Order'
9
+ }
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'Line decor, dynamic - new pattern, line_decor_pre, ansi' {
6
+ spec_mde_dname_doc_blocks_expect docs/dev/line-decor-dynamic.md \
7
+ $'\e[38;2;200;200;33m\e[48;2;60;60;32mSpecies\e[0m'
8
+ }
@@ -209,6 +209,16 @@ spec_mde_args_grep_filter_expect () {
209
209
  [[ -n $status ]]
210
210
  }
211
211
 
212
+ spec_mde_dname_doc_blocks_expect () {
213
+ BATS_SAFE=_
214
+ spec_mde_args_expect "$1" \
215
+ "${@:2:$(($#-2))}" \
216
+ --list-blocks-message dname \
217
+ --list-blocks-type 3 \
218
+ --list-blocks \
219
+ "${!#}"
220
+ }
221
+
212
222
  spec_mde_xansi_dname_doc_blocks_expect () {
213
223
  BATS_OUTPUT_FILTER=A
214
224
  BATS_SAFE=_
@@ -12,10 +12,6 @@ __filedirs_all()
12
12
  COMPREPLY='.'
13
13
  }
14
14
 
15
- _mde_echo_version() {
16
- echo "2.8.1"
17
- }
18
-
19
15
  _mde() {
20
16
  local cur prev opts
21
17
  cur="${COMP_WORDS[COMP_CWORD]}"
@@ -213,4 +209,3 @@ _mde() {
213
209
  }
214
210
 
215
211
  complete -o filenames -o nospace -F _mde mde
216
- # _mde_echo_version
@@ -12,10 +12,6 @@ __filedirs_all()
12
12
  COMPREPLY='.'
13
13
  }
14
14
 
15
- _mde_echo_version() {
16
- echo "<%= MarkdownExec::VERSION %>"
17
- }
18
-
19
15
  _mde() {
20
16
  local cur prev opts
21
17
  cur="${COMP_WORDS[COMP_CWORD]}"
@@ -104,4 +100,3 @@ _mde() {
104
100
  }
105
101
 
106
102
  complete -o filenames -o nospace -F _mde mde
107
- # _mde_echo_version
@@ -0,0 +1,18 @@
1
+ ``` :(hidden)
2
+ ```
3
+ ``` :visible
4
+ ```
5
+ / ux block is displayed differently than other types
6
+ ```ux :()
7
+ name: name
8
+ ```
9
+ @import bats-document-configuration.md
10
+ ```opts :(document_opts)
11
+ # Pattern for blocks to hide from user-selection
12
+ block_name_include_match:
13
+ ^\(.*\)$
14
+
15
+ # Pattern for the block name in the line defining the block
16
+ block_name_match: |
17
+ :(?<title>\S+)( |$)
18
+ ```
@@ -0,0 +1,21 @@
1
+ / This automatic block sets VAR and displays the current value in the menu.
2
+ ```ux :[document_ux_VAR]
3
+ default: :echo
4
+ echo: $(basename `pwd`)
5
+ name: VAR
6
+ ```
7
+ / This block is not visible. Execute to display the inherited lines for testing.
8
+ ```opts :(menu_with_inherited_lines)
9
+ menu_with_inherited_lines: true
10
+ ```
11
+ / This block is not visible. Execute to set a new value, displayed by the block above.
12
+ ```ux :(VAR_has_count)
13
+ echo: $(basename `pwd` | wc -c)
14
+ name: VAR
15
+ ```
16
+ / This block is visible. Execute to set a new value, displayed by the block above.
17
+ ```ux :[IAB_has_count]
18
+ echo: $VAR$VAR
19
+ name: IAB
20
+ ```
21
+ @import bats-document-configuration.md
@@ -0,0 +1,9 @@
1
+ / an automatic UX block that has a precondition that must be met before it is executed
2
+ ```ux :[document_ux_SPECIES]
3
+ default: :exec
4
+ exec: printf "$MISSING_VARIABLE"
5
+ name: SPECIES
6
+ preconditions:
7
+ - MISSING_VARIABLE
8
+ ```
9
+ @import bats-document-configuration.md
@@ -0,0 +1,7 @@
1
+ / This automatic block sets VAR and displays the current value in the menu.
2
+ ```ux :[document_ux_VAR]
3
+ default: Pongo tapanuliensis
4
+ name: SPECIES
5
+ readonly: true
6
+ ```
7
+ @import bats-document-configuration.md
@@ -0,0 +1,32 @@
1
+ / an automatic UX block requires a shell block and another UX block
2
+ ``` :(shell)
3
+ ENTITY='Pongo tapanuliensis,Pongo'
4
+ ```
5
+ ```ux :[document_ux_SPECIES] +(shell) +[ux_GENUS]
6
+ default: :exec
7
+ exec: echo "${ENTITY%%,*}"
8
+ name: SPECIES
9
+ transform: :chomp
10
+ ```
11
+ / required ux block requires another
12
+ ```ux :[ux_GENUS] +[ux_NAME]
13
+ default: :exec
14
+ exec: echo "${ENTITY##*,}"
15
+ name: GENUS
16
+ transform: :chomp
17
+ ```
18
+ / executed in context of prior ux blocks, uses their initial values
19
+ ```ux :[ux_NAME]
20
+ default: :exec
21
+ exec: echo "$SPECIES - $GENUS"
22
+ name: NAME
23
+ transform: :chomp
24
+ ```
25
+ / executed after other ux blocks, uses their initial values
26
+ ```ux :[document_ux_NAME2]
27
+ default: :exec
28
+ exec: echo "$NAME"
29
+ name: NAME2
30
+ transform: :chomp
31
+ ```
32
+ @import bats-document-configuration.md
@@ -0,0 +1,11 @@
1
+ / Retain whitespace in output from shell blocks
2
+ ``` :[make-output]
3
+ echo 'Species'
4
+ echo -e " Genus\n Family\tOrder"
5
+ ```
6
+ @import bats-document-configuration.md
7
+ ```opts :(document_opts)
8
+ line_decor_pre:
9
+ - :color_method: :ansi_38_2_200_200_33__48_2_60_60_32__0
10
+ :pattern: '%([^_]{0,64})%'
11
+ ```
@@ -0,0 +1,9 @@
1
+ / Demonstrate dynamic color names
2
+ / line_decor_pre is performed before line_decor_main and line_decor_post
3
+ %Species%
4
+ @import bats-document-configuration.md
5
+ ```opts :(document_opts)
6
+ line_decor_pre:
7
+ - :color_method: :ansi_38_2_200_200_33__48_2_60_60_32__0
8
+ :pattern: '%([^_]{0,64})%'
9
+ ```
data/lib/ansi_string.rb CHANGED
@@ -14,6 +14,15 @@ class AnsiString < String
14
14
  def method_missing(method_name, *args, &block)
15
15
  if dynamic_color_method?(method_name)
16
16
  case method_name.to_s
17
+ when /^ansi_/
18
+ segments = $'.split('__')
19
+ codes = ''
20
+ segments[0..-2].each do |segment|
21
+ codes += "\033[#{segment.split('_').join(';')}m"
22
+ end
23
+ codes += self.to_s
24
+ codes += "\033[#{segments.last.split('_').join(';')}m"
25
+ self.class.new(codes)
17
26
  when /^fg_bg_rgb_/
18
27
  bytes = $'.split('_')
19
28
  fg_bg_rgb_color(bytes[0..2].join(';'), bytes[3..5].join(';'))
@@ -148,6 +157,6 @@ class AnsiString < String
148
157
  # @param method_name [Symbol] The name of the method being checked.
149
158
  # @return [Boolean] True if the method name matches a dynamic color method.
150
159
  def dynamic_color_method?(method_name)
151
- method_name.to_s =~ /^(fg_bg_rgb_|fg_bg_rgbh_|fg_rgb_|fg_rgbh_)/
160
+ method_name.to_s =~ /^(ansi_|fg_bg_rgb_|fg_bg_rgbh_|fg_rgb_|fg_rgbh_)/
152
161
  end
153
162
  end
data/lib/fcb.rb CHANGED
@@ -14,15 +14,19 @@ def parse_yaml_of_ux_block(
14
14
  export = data['export']
15
15
  export = data if export.nil?
16
16
  name = export['name']
17
- raise "Invalid data: #{data.inspect}" unless name.present?
17
+
18
+ raise "Name is missing in UX block: #{data.inspect}" unless name.present?
18
19
 
19
20
  OpenStruct.new(
20
21
  allowed: export['allowed'],
21
22
  default: export['default'],
23
+ echo: export['echo'],
22
24
  exec: export['exec'],
23
25
  menu_format: export['menu_format'] || menu_format,
24
26
  name: name,
27
+ preconditions: export['preconditions'],
25
28
  prompt: export['prompt'] || prompt,
29
+ readonly: export['readonly'].nil? ? false : export['readonly'],
26
30
  transform: export['transform'],
27
31
  validate: export['validate'] || validate
28
32
  )
@@ -135,7 +139,9 @@ module MarkdownExec
135
139
 
136
140
  @attrs[:center] = table_center
137
141
  oname = @attrs[:oname] = format(export.menu_format, export.to_h)
142
+ @attrs[:readonly] = export.readonly
138
143
  else
144
+ # triggered by an empty block
139
145
  raise "Invalid data type: #{data.inspect}"
140
146
  end
141
147
  end
@@ -146,8 +152,6 @@ module MarkdownExec
146
152
  )
147
153
  end
148
154
 
149
- private
150
-
151
155
  # Formats multiline body content as a title string.
152
156
  # indents all but first line with two spaces
153
157
  # so it displays correctly in menu.
@@ -179,6 +183,17 @@ module MarkdownExec
179
183
 
180
184
  public
181
185
 
186
+ def name_in_menu!(indented_multi_line)
187
+ # Indent has been extracted from the first line,
188
+ # remove indent from the remaining lines.
189
+ @attrs[:dname] =
190
+ if @attrs[:indent].empty?
191
+ indented_multi_line
192
+ else
193
+ indented_multi_line.gsub("\n#{@attrs[:indent]}", "\n")
194
+ end
195
+ end
196
+
182
197
  def respond_to_missing?(method_name, include_private = false)
183
198
  @attrs.key?(method_name.to_sym) || super
184
199
  end
@@ -253,8 +268,8 @@ if $PROGRAM_NAME == __FILE__
253
268
  end
254
269
 
255
270
  def sort_hash_recursively(hash)
256
- hash.each_with_object({}) do |(k, v), new_hash|
257
- new_hash[k] = v.is_a?(Hash) ? sort_hash_recursively(v) : v
271
+ hash.transform_values do |v|
272
+ v.is_a?(Hash) ? sort_hash_recursively(v) : v
258
273
  end.sort.to_h
259
274
  end
260
275
 
data/lib/filter.rb CHANGED
@@ -127,8 +127,9 @@ module MarkdownExec
127
127
  filters[:fcb_chrome] = fcb.fetch(:chrome, false)
128
128
  filters[:shell_default] = (fcb.type == BlockType::SHELL)
129
129
 
130
- if options[:block_disable_match].present? &&
131
- fcb.start_line =~ Regexp.new(options[:block_disable_match])
130
+ if fcb.readonly ||
131
+ (options[:block_disable_match].present? &&
132
+ fcb.start_line =~ Regexp.new(options[:block_disable_match]))
132
133
  fcb.disabled = TtyMenu::DISABLE
133
134
  end
134
135
  return unless name.present?