markdown_exec 2.8.0 → 2.8.1

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: c36bb5c2d9e91eeeae59067f91fc88a3ad8e6b1a27ebfb474ff900903d030042
4
- data.tar.gz: b002fc24e78006e830fdc66bb0be4df05fe9df62e6c036965eefbb7047f37ec7
3
+ metadata.gz: d752af0db5e1c1a770b64f9341c3d08e1e9bc8612230a9cb44ddc7fddc4c3051
4
+ data.tar.gz: 5ba8524b3323bd8333b82a5d0607fbb9db59a5157a1c7ae0564b3f624f26addd
5
5
  SHA512:
6
- metadata.gz: 8eedac9012c2c0103afe99a8ea0cd235b26b3ab62618b35d79af6f685a56195818d28ba70588f93d754c76e5c4b3bb524de0ed09fd97864bdc79a424015911a9
7
- data.tar.gz: d24b8c56e50416032de644f00d11f6bb81689617e47da57ec1e4b39a693c867dedff268ddd00e023bc134fc40ee9ae9b452a808131d129b378508464ac0793f5
6
+ metadata.gz: 29b210e56b46a1edf099c02267e2b3c7cdae6701f7ee99d5a946d06eea7272da3534765110ec36a6de017a10d0f4833c9075c27dacb0cec8b050192d3892d748
7
+ data.tar.gz: e73cd906ce9035c8c78d2e301866af4a76bc7a730c5109fc8cc59ecf64679cb578fb04b324e700df064886d250c394c441f77850b9e21230d346d08bd92a9a5f
data/.rubocop.yml CHANGED
@@ -97,6 +97,9 @@ Style/GlobalVars:
97
97
  Style/IfUnlessModifier: # 2024-08 suggests lines that are too long
98
98
  Enabled: false
99
99
 
100
+ Style/KeywordParametersOrder:
101
+ Enabled: false
102
+
100
103
  Style/Lambda:
101
104
  Enabled: false
102
105
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (2.8.0)
4
+ markdown_exec (2.8.1)
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 'Initial values' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/block-type-ux-auto.md \
7
+ 'v1 = _v2 = _v3 = 12_v4 = 21_v5 = markdown_exec_v6 = 31'
8
+ }
@@ -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-exec.md \
7
+ "ux0=_ux1=Unknown_ux2=markdown_exec_ux3=markdown_exec_ux4=Xform: 'markdown'"
8
+ }
@@ -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
+ }
@@ -13,7 +13,7 @@ __filedirs_all()
13
13
  }
14
14
 
15
15
  _mde_echo_version() {
16
- echo "2.8.0"
16
+ echo "2.8.1"
17
17
  }
18
18
 
19
19
  _mde() {
@@ -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
@@ -100,8 +100,10 @@ end
100
100
 
101
101
  # selected block and subsequent menu state
102
102
  #
103
+ BlockSelection = Struct.new(:id)
103
104
  SelectedBlockMenuState = Struct.new(:block, :source, :state)
104
105
 
105
106
  class TtyMenu
107
+ ENABLE = nil
106
108
  DISABLE = ''
107
109
  end
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
@@ -934,7 +934,12 @@ module MarkdownExec
934
934
  end
935
935
  end
936
936
 
937
- # private
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, (inherited_code || []) + required[:code])
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
- # if the same menu is being displayed, collect the display name
1985
- # of the selected menu item for use as the default item
1986
- [lfls.link_state,
1987
- lfls.load_file == LoadFile::LOAD ? nil : selected.dname,
1988
- # 2024-08-22 true to quit
1989
- lfls.load_file == LoadFile::EXIT]
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
- @dml_link_state, @dml_menu_default_dname, quit =
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
- :break if quit
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.sort.map do |file|
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
- pause_now = false
2330
- row_attrib = :row
2331
- loop do
2332
- if pause_now && (prompt_select_continue == MenuState::EXIT)
2333
- break
2334
- end
2335
-
2336
- # menu with Back and Facet options at top
2337
- case (name = prompt_select_code_filename(
2338
- [exit_prompt,
2339
- @delegate_object[:prompt_filespec_facet]] +
2340
- files_table_rows.map(&row_attrib),
2341
- string: @delegate_object[:prompt_select_history_file],
2342
- color_sym: :prompt_color_after_script_execution
2343
- ))
2344
- when exit_prompt
2345
- break
2346
- when @delegate_object[:prompt_filespec_facet]
2347
- row_attrib = row_attrib == :row ? :file : :row
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
- nil
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: @dml_menu_default_dname
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
- @dml_menu_default_dname = nil
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 == :break
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
- prior_answer.index || prior_answer.name
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)
@@ -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.8.0'
10
+ VERSION = '2.8.1'
11
11
  end
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 = collect_unique_names(dependencies).push(nickname).uniq
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) || all_dependency_names.include?(fcb.nickname) || all_dependency_names.include?(fcb.oname)
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
- unmet_dependencies.delete(fcb.pub_name) || unmet_dependencies.delete(fcb.nickname) || unmet_dependencies.delete(fcb.oname) # may not exist if block name is duplicated
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(anyname:, block_source:, label_body: true, label_format_above: nil,
128
- label_format_below: nil)
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(fcb, block_source, label_format_above,
154
- label_format_below)
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
- if fcb.collapsible
234
- fcb.s1decorated = fcb.s1decorated + ' ' + (fcb.collapse ? opts[:menu_collapsible_symbol_collapsed] : opts[:menu_collapsible_symbol_expanded])
235
- end
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, current, next_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({ block_name: block_name_for_bash_comment }))
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({ block_name: block_name_for_bash_comment }))
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(array,
419
- last_selected_placeholder = nil, next_selected_placeholder = nil)
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).with('source1').returns(OpenStruct.new(reqs: ['source2']))
467
- @mdoc.stubs(:get_block_by_anyname).with('source2').returns(OpenStruct.new(reqs: []))
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, block_name_hidden_match: 'block1' }
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'], 'block1' => ['block2'], 'block2' => nil }),
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([OpenStruct.new(oname: 'block4',
589
- wraps: ['wrap4'])]).map(&:oname)
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.0
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-10 00:00:00.000000000 Z
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