markdown_exec 2.7.1 → 2.7.2

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: 2777165b185482931d9fe8e519921490e8e252dcb93d141abf52fc6e53b95ba7
4
- data.tar.gz: c5925bd62f6853ad701946a2ecca3bf57c8b967b7f65c9990f72c17748591398
3
+ metadata.gz: bf1cce75f6ae919ebb237862e74ade141e6300426e514331b4410cf7cfa0b27e
4
+ data.tar.gz: 2ea6f8f6fa47f01b324b6663c6c1dcd0f69a0c2a164d7591f5c714d9618b90a4
5
5
  SHA512:
6
- metadata.gz: 0f534d77704be9418666e804a2bf1ecfd6c41ae4cee8b0c7f3c7753f2967b88b257e1962f3f8dc9565af09a697f75fb823054f062bffea9a7aabef9d9bae885e
7
- data.tar.gz: 18bcdb411c4655bb3f99c8e7557adf7d872c0562fcfeef18700134578dcc9c8e8ecf9992c43c82521eb773aad6d97a95e7f6859d90a36ded25a2ac88e3a2babc
6
+ metadata.gz: 87b6c3f35b0fd85b06dc1d94afc6c145fd27989def6972dcaf66e85a8c899e3550376efa9b0e70efe2327e403a46615b6c51a5210653bf5bdd0e1c6946d477f7
7
+ data.tar.gz: 78fd6cb33feabb7a94c0df274528cf2ffd0d4b60e1bf37328304a125b71edc44c6fd884c003af7088b0953923cee3e3a2b3f39b139b1559bf0b2b4337792ecc9
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (2.7.1)
4
+ markdown_exec (2.7.2)
5
5
  clipboard (~> 1.3.6)
6
6
  open3 (~> 0.1.1)
7
7
  optparse (~> 0.1.1)
data/bats/border.bats ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'Border - ' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/border.md \
7
+ 'A: 1_ B: 2_'
8
+ }
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bats
2
+
3
+ load 'test_helper'
4
+
5
+ @test 'document_shell - required' {
6
+ spec_mde_xansi_dname_doc_blocks_expect docs/dev/document-shell.md \
7
+ --dump-inherited-lines t '* Exit' \
8
+ ' inherited_lines_ - : : from required_ - : : from document_shell'
9
+ }
@@ -13,7 +13,7 @@ __filedirs_all()
13
13
  }
14
14
 
15
15
  _mde_echo_version() {
16
- echo "2.7.1"
16
+ echo "2.7.2"
17
17
  }
18
18
 
19
19
  _mde() {
@@ -5,6 +5,10 @@ VAULT: 1
5
5
  echo "Species: $Species"
6
6
  echo "VAULT: $VAULT"
7
7
  ```
8
+ | Variable| Value
9
+ | -| -
10
+ | Species| ${Species}
11
+ | VAULT| ${VAULT}
8
12
  @import bats-document-configuration.md
9
13
  ```vars :(document_vars)
10
14
  Species: Not specified
@@ -0,0 +1,7 @@
1
+ ```vars
2
+ A: 1
3
+ B: 2
4
+ ```
5
+ @import bats-document-configuration.md
6
+ ```opts :(document_opts)
7
+ ```
@@ -11,6 +11,7 @@ echo "current base name is now $(basename `pwd`)"
11
11
  ```link
12
12
  load: file_$(basename `pwd`).sh
13
13
  ```
14
+ / This should not be evaluated $(err). It errs with "Error: HashDelegator.blocks_from_nested_files -- Shell script execution failed: /bin/bash: line 2: err: command not found"
14
15
  @import bats-document-configuration.md
15
16
  ```opts :(document_opts)
16
17
  heading1_center: false
@@ -0,0 +1,6 @@
1
+ ```bash :(required)
2
+ : from required
3
+ ```
4
+ ```bash :(document_shell) +(required)
5
+ : from document_shell
6
+ ```
data/lib/fcb.rb CHANGED
@@ -35,6 +35,14 @@ module MarkdownExec
35
35
  }.merge(options)
36
36
  end
37
37
 
38
+ def code_name_included?(*names)
39
+ names.include?(@attrs[:oname])
40
+ end
41
+
42
+ def code_name_exp?(regexp)
43
+ Regexp.new(regexp) =~ @attrs[:oname]
44
+ end
45
+
38
46
  # Derives a title from the body of an FCB object.
39
47
  # @param fcb [Object] The FCB object whose title is to be derived.
40
48
  # @return [String] The derived title.
@@ -152,23 +160,27 @@ module MarkdownExec
152
160
  @attrs.to_yaml
153
161
  end
154
162
 
155
- # Expand variables in `dname` and `body` attributes
163
+ # Expand variables in attributes
164
+ ####
156
165
  def expand_variables_in_attributes!(pattern, replacements)
157
- ### update name, nickname, title, label ???
158
-
159
- # Replace variables in `dname` using the replacements dictionary
166
+ @attrs[:raw_dname] ||= @attrs[:dname]
160
167
  @attrs[:dname] = @attrs[:dname]&.gsub(pattern) do |match|
161
168
  replacements[match]
162
169
  end
170
+
171
+ @attrs[:raw_s0printable] ||= @attrs[:s0printable]
163
172
  @attrs[:s0printable] = @attrs[:s0printable]&.gsub(pattern) do |match|
164
173
  replacements[match]
165
174
  end
175
+
176
+ @attrs[:raw_s1decorated] ||= @attrs[:s1decorated]
166
177
  @attrs[:s1decorated] = @attrs[:s1decorated]&.gsub(pattern) do |match|
167
178
  replacements[match]
168
179
  end
169
180
 
170
181
  # Replace variables in each line of `body` if `body` is present
171
182
  if @attrs[:body]
183
+ @attrs[:raw_body] ||= @attrs[:body]
172
184
  @attrs[:body] = @attrs[:body]&.map do |line|
173
185
  if line.empty?
174
186
  line
data/lib/filter.rb CHANGED
@@ -136,14 +136,14 @@ module MarkdownExec
136
136
  if options[:hide_blocks_by_name]
137
137
  filters[:hidden_name] =
138
138
  !!(options[:block_name_hidden_match].present? &&
139
- name =~ Regexp.new(options[:block_name_hidden_match]))
139
+ fcb.code_name_exp?(options[:block_name_hidden_match]))
140
140
  end
141
141
  filters[:include_name] =
142
142
  !!(options[:block_name_include_match].present? &&
143
- name =~ Regexp.new(options[:block_name_include_match]))
143
+ fcb.code_name_exp?(options[:block_name_include_match]))
144
144
  filters[:wrap_name] =
145
145
  !!(options[:block_name_wrapper_match].present? &&
146
- name =~ Regexp.new(options[:block_name_wrapper_match]))
146
+ fcb.code_name_exp?(options[:block_name_wrapper_match]))
147
147
  end
148
148
 
149
149
  # Evaluates the filter settings to make a final decision on
@@ -227,27 +227,6 @@ if $PROGRAM_NAME == __FILE__
227
227
  require_relative 'constants'
228
228
 
229
229
  module MarkdownExec
230
- # Define a mock fenced code block class for testing purposes
231
- class FCB
232
- attr_accessor :chrome, :disabled, :oname, :shell, :start_line, :type
233
-
234
- def initialize(
235
- chrome: false, dname: nil, oname: nil,
236
- shell: '', start_line: nil, type: nil
237
- )
238
- @chrome = chrome
239
- @dname = dname
240
- @oname = oname
241
- @shell = shell
242
- @type = type
243
- @start_line = start_line
244
- end
245
-
246
- def fetch(key, default)
247
- instance_variable_get("@#{key}") || default
248
- end
249
- end
250
-
251
230
  class FilterTest < Minitest::Test
252
231
  def setup
253
232
  @options = {}
@@ -361,10 +361,10 @@ module HashDelegatorSelf
361
361
  # @param [String] line The line to be processed.
362
362
  # @param [Array<Symbol>] selected_types A list of message types to check.
363
363
  # @param [Proc] block The block to be called with the line data.
364
- def yield_line_if_selected(line, selected_types, id: '', &block)
364
+ def yield_line_if_selected(line, selected_types, source_id: '', &block)
365
365
  return unless block && block_type_selected?(selected_types, :line)
366
366
 
367
- block.call(:line, MarkdownExec::FCB.new(body: [line], id: id))
367
+ block.call(:line, MarkdownExec::FCB.new(body: [line], id: source_id))
368
368
  end
369
369
  end
370
370
 
@@ -600,52 +600,72 @@ module MarkdownExec
600
600
  end
601
601
  end
602
602
 
603
- def add_back_option(id: '', menu_blocks:)
604
- append_chrome_block(id: id, menu_blocks: menu_blocks,
605
- menu_state: MenuState::BACK)
603
+ def add_back_option(menu_blocks:, source_id: '')
604
+ append_chrome_block(
605
+ menu_blocks: menu_blocks,
606
+ menu_state: MenuState::BACK,
607
+ source_id: source_id
608
+ )
606
609
  end
607
610
 
608
- def add_exit_option(id: '', menu_blocks:)
609
- append_chrome_block(id: id, menu_blocks: menu_blocks,
610
- menu_state: MenuState::EXIT)
611
+ def add_exit_option(menu_blocks:, source_id: '')
612
+ append_chrome_block(
613
+ menu_blocks: menu_blocks,
614
+ menu_state: MenuState::EXIT,
615
+ source_id: source_id
616
+ )
611
617
  end
612
618
 
613
- def add_inherited_lines(menu_blocks:, link_state:)
614
- append_inherited_lines(menu_blocks: menu_blocks, link_state: link_state)
619
+ def add_inherited_lines(link_state:, menu_blocks:)
620
+ append_inherited_lines(
621
+ link_state: link_state,
622
+ menu_blocks: menu_blocks
623
+ )
615
624
  end
616
625
 
617
626
  # Modifies the provided menu blocks array by adding 'Back' and 'Exit' options,
618
627
  # along with initial and final dividers, based on the delegate object's configuration.
619
628
  #
620
629
  # @param menu_blocks [Array] The array of menu block elements to be modified.
621
- def add_menu_chrome_blocks!(id: '', menu_blocks:, link_state:)
630
+ def add_menu_chrome_blocks!(link_state:, menu_blocks:, source_id: '')
622
631
  return unless @delegate_object[:menu_link_format].present?
623
632
 
624
- if @delegate_object[:menu_with_inherited_lines]
625
- add_inherited_lines(menu_blocks: menu_blocks,
626
- link_state: link_state)
627
- end
633
+ add_inherited_lines(
634
+ link_state: link_state,
635
+ menu_blocks: menu_blocks
636
+ ) if @delegate_object[:menu_with_inherited_lines]
628
637
 
629
638
  # back before exit
630
- add_back_option(id: "#{id}.back",
631
- menu_blocks: menu_blocks) if should_add_back_option?
639
+ add_back_option(
640
+ menu_blocks: menu_blocks,
641
+ source_id: "#{source_id}.back"
642
+ ) if should_add_back_option?
632
643
 
633
644
  # exit after other options
634
- if @delegate_object[:menu_with_exit]
635
- add_exit_option(id: "#{id}.exit", menu_blocks: menu_blocks)
636
- end
637
645
 
638
- append_divider(id: "#{id}.init", menu_blocks: menu_blocks,
639
- position: :initial)
640
- append_divider(id: "#{id}.final", menu_blocks: menu_blocks,
641
- position: :final)
646
+ add_exit_option(
647
+ menu_blocks: menu_blocks,
648
+ source_id: "#{source_id}.exit"
649
+ ) if @delegate_object[:menu_with_exit]
650
+
651
+ append_divider(
652
+ menu_blocks: menu_blocks,
653
+ position: :initial,
654
+ source_id: "#{source_id}.init"
655
+ )
656
+
657
+ append_divider(
658
+ menu_blocks: menu_blocks,
659
+ position: :final,
660
+ source_id: "#{source_id}.final"
661
+ )
642
662
  end
643
663
 
644
664
  # Appends a chrome block, which is a menu option for Back or Exit
645
665
  #
646
666
  # @param all_blocks [Array] The current blocks in the menu
647
667
  # @param type [Symbol] The type of chrome block to add (:back or :exit)
648
- def append_chrome_block(menu_blocks:, menu_state:, id: '')
668
+ def append_chrome_block(menu_blocks:, menu_state:, source_id: '')
649
669
  case menu_state
650
670
  when MenuState::BACK
651
671
  history_state_partition
@@ -683,7 +703,7 @@ module MarkdownExec
683
703
  dname: HashDelegator.new(@delegate_object).string_send_color(
684
704
  formatted_name, :menu_chrome_color
685
705
  ),
686
- id: id,
706
+ id: source_id.to_s,
687
707
  type: BlockType::CHROME,
688
708
  nickname: formatted_name,
689
709
  oname: formatted_name
@@ -703,10 +723,10 @@ module MarkdownExec
703
723
  #
704
724
  # @param menu_blocks [Array] The array of menu block elements.
705
725
  # @param position [Symbol] The position to insert the divider (:initial or :final).
706
- def append_divider(id: '', menu_blocks:, position:)
726
+ def append_divider(menu_blocks:, position:, source_id: '')
707
727
  return unless divider_formatting_present?(position)
708
728
 
709
- divider = create_divider(position, id: id)
729
+ divider = create_divider(position, source_id: source_id)
710
730
  position == :initial ? menu_blocks.unshift(divider) : menu_blocks.push(divider)
711
731
  end
712
732
 
@@ -715,7 +735,7 @@ module MarkdownExec
715
735
  #
716
736
  # @param menu_blocks [Array] The array of menu block elements.
717
737
  # @param position [Symbol] The position to insert the divider (:initial or :final).
718
- def append_inherited_lines(menu_blocks:, link_state:, position: top)
738
+ def append_inherited_lines(link_state:, menu_blocks:, position: top)
719
739
  return unless link_state.inherited_lines_present?
720
740
 
721
741
  insert_at_top = @delegate_object[:menu_inherited_lines_at_top]
@@ -783,13 +803,31 @@ module MarkdownExec
783
803
 
784
804
  # private
785
805
 
806
+ def expand_references!(fcb, link_state)
807
+ expand_variable_references!(
808
+ blocks: [fcb],
809
+ initial_code_required: false,
810
+ link_state: link_state
811
+ )
812
+ expand_variable_references!(
813
+ blocks: [fcb],
814
+ echo_format: '%s',
815
+ group_name: :command,
816
+ initial_code_required: false,
817
+ key_format: '$(%s)',
818
+ link_state: link_state,
819
+ pattern: options_command_substitution_regexp
820
+ )
821
+ end
822
+
786
823
  # Iterates through nested files to collect various types
787
824
  # of blocks, including dividers, tasks, and others.
788
825
  # The method categorizes blocks based on their type and processes them accordingly.
789
826
  #
790
827
  # @return [Array<FCB>] An array of FCB objects representing the blocks.
791
828
  def blocks_from_nested_files(
792
- link_state: @dml_link_state || LinkState.new
829
+ link_state: @dml_link_state || LinkState.new,
830
+ source_id: nil
793
831
  )
794
832
  register_console_attributes(@delegate_object)
795
833
  @decor_patterns_from_delegate_object_for_block_create = collect_line_decor_patterns(@delegate_object)
@@ -799,22 +837,6 @@ module MarkdownExec
799
837
  iter_blocks_from_nested_files do |btype, fcb|
800
838
  count += 1
801
839
 
802
- # text substitution in menu
803
- #
804
- expand_references = lambda do |fcb|
805
- expand_variable_references!(blocks: [fcb], link_state: link_state,
806
- initial_code_required: false)
807
- expand_variable_references!(
808
- blocks: [fcb],
809
- echo_format: '%s',
810
- initial_code_required: false,
811
- key_format: '$(%s)',
812
- link_state: link_state,
813
- group_name: :command,
814
- pattern: options_command_substitution_regexp
815
- )
816
- end
817
-
818
840
  case btype
819
841
  when :blocks
820
842
  if @delegate_object[:bash]
@@ -822,20 +844,25 @@ module MarkdownExec
822
844
  block_calls_scan: @delegate_object[:block_calls_scan],
823
845
  block_name_match: @delegate_object[:block_name_match],
824
846
  block_name_nick_match: @delegate_object[:block_name_nick_match],
825
- id: "*#{count}"
847
+ id: "#{source_id}_bfnf_b_#{count}"
826
848
  ) do |oname, color|
827
849
  apply_block_type_color_option(oname, color)
828
850
  end
851
+ else
852
+ expand_references!(fcb, link_state)
829
853
  end
830
- expand_references.call(fcb)
831
854
  blocks << fcb
832
855
  when :filter # types accepted
833
856
  %i[blocks line]
834
857
  when :line
835
858
  unless @delegate_object[:no_chrome]
836
- expand_references.call(fcb)
837
- create_and_add_chrome_blocks(blocks, fcb, id: "*#{count}",
838
- init_ids: init_ids)
859
+ # expand references only if block is recognized (not a comment)
860
+ create_and_add_chrome_blocks(
861
+ blocks, fcb, id: "#{source_id}_bfnf_l_#{count}", init_ids: init_ids
862
+ ) do
863
+ # expand references only if block is recognized (not a comment)
864
+ expand_references!(fcb, link_state)
865
+ end
839
866
  end
840
867
  end
841
868
  end
@@ -1134,8 +1161,10 @@ module MarkdownExec
1134
1161
  end
1135
1162
 
1136
1163
  # Check if the expression contains wildcard characters
1137
- def contains_wildcards?(expr)
1138
- expr.match(%r{\*|\?|\[})
1164
+ def contains_glob?(str)
1165
+ return false if str.nil?
1166
+
1167
+ str.match?(/[\*\?\[\{\}]/)
1139
1168
  end
1140
1169
 
1141
1170
  def copy_to_clipboard(required_lines)
@@ -1200,7 +1229,8 @@ module MarkdownExec
1200
1229
  collapse: nil, color_method:, decor_patterns: [],
1201
1230
  disabled: true, format_option:, id: '',
1202
1231
  level: 0, match_data:, type: '',
1203
- wrap: nil
1232
+ wrap: nil,
1233
+ fcb: nil
1204
1234
  )
1205
1235
  line_cap = NamedCaptureExtractor.extract_named_group2(match_data)
1206
1236
  # replace tabs in indent
@@ -1256,23 +1286,44 @@ module MarkdownExec
1256
1286
  )
1257
1287
 
1258
1288
  line_obj[:line] = line_obj[:indent] + line_obj[:text]
1259
- blocks.push FCB.new(
1260
- center: center,
1261
- chrome: true,
1262
- collapse: collapse.nil? ? (line_obj[:collapse] == COLLAPSIBLE_TOKEN_COLLAPSE) : collapse,
1263
- token: line_obj[:collapse],
1264
- disabled: disabled ? TtyMenu::DISABLE : nil,
1265
- id: "#{id}.#{index}",
1266
- level: level,
1267
- s0indent: indent,
1268
- s0printable: line_obj[:text],
1269
- s1decorated: decorated,
1270
- dname: line_obj[:indent] + decorated,
1271
- indent: line_obj[:indent],
1272
- oname: line_obj[:text],
1273
- text: line_obj[:text],
1274
- type: type
1275
- )
1289
+
1290
+ if fcb.nil?
1291
+ fcb = FCB.new(
1292
+ center: center,
1293
+ chrome: true,
1294
+ collapse: collapse.nil? ? (line_obj[:collapse] == COLLAPSIBLE_TOKEN_COLLAPSE) : collapse,
1295
+ token: line_obj[:collapse],
1296
+ disabled: disabled ? TtyMenu::DISABLE : nil,
1297
+ id: "#{id}.#{index}",
1298
+ level: level,
1299
+ s0indent: indent,
1300
+ s0printable: line_obj[:text],
1301
+ s1decorated: decorated,
1302
+ dname: line_obj[:indent] + decorated,
1303
+ indent: line_obj[:indent],
1304
+ oname: line_obj[:text],
1305
+ text: line_obj[:text],
1306
+ type: type
1307
+ )
1308
+ else
1309
+ fcb.center = center
1310
+ fcb.chrome = true
1311
+ fcb.collapse = collapse.nil? ? (line_obj[:collapse] == COLLAPSIBLE_TOKEN_COLLAPSE) : collapse
1312
+ fcb.token = line_obj[:collapse]
1313
+ fcb.disabled = disabled ? TtyMenu::DISABLE : nil
1314
+ fcb.id = "#{id}.#{index}"
1315
+ fcb.level = level
1316
+ fcb.s0indent = indent
1317
+ fcb.s0printable = line_obj[:text]
1318
+ fcb.s1decorated = decorated
1319
+ fcb.dname = line_obj[:indent] + decorated
1320
+ fcb.indent = line_obj[:indent]
1321
+ fcb.oname = line_obj[:text]
1322
+ fcb.text = line_obj[:text]
1323
+ fcb.type = type
1324
+ end
1325
+
1326
+ blocks.push fcb
1276
1327
  end
1277
1328
  line_caps.count
1278
1329
  end
@@ -1292,6 +1343,12 @@ module MarkdownExec
1292
1343
  next
1293
1344
  end
1294
1345
 
1346
+ if block_given?
1347
+ # expand references only if block is recognized (not a comment)
1348
+ yield if block_given?
1349
+ mbody = fcb.body[0].match @delegate_object[criteria[:match]]
1350
+ end
1351
+
1295
1352
  create_and_add_chrome_block(
1296
1353
  blocks: blocks,
1297
1354
  case_conversion: criteria[:case_conversion],
@@ -1312,6 +1369,7 @@ module MarkdownExec
1312
1369
  decor_patterns:
1313
1370
  @decor_patterns_from_delegate_object_for_block_create,
1314
1371
  disabled: !(criteria[:collapsible] && @delegate_object[criteria[:collapsible]]),
1372
+ fcb: fcb,
1315
1373
  id: "#{id}.#{index}",
1316
1374
  format_option: criteria[:format] &&
1317
1375
  @delegate_object[criteria[:format]],
@@ -1324,7 +1382,7 @@ module MarkdownExec
1324
1382
  end
1325
1383
  end
1326
1384
 
1327
- def create_divider(position, id: '')
1385
+ def create_divider(position, source_id: '')
1328
1386
  divider_key = if position == :initial
1329
1387
  :menu_initial_divider
1330
1388
  else
@@ -1337,7 +1395,7 @@ module MarkdownExec
1337
1395
  chrome: true,
1338
1396
  disabled: TtyMenu::DISABLE,
1339
1397
  dname: string_send_color(oname, :menu_divider_color),
1340
- id: id,
1398
+ id: source_id,
1341
1399
  oname: oname
1342
1400
  )
1343
1401
  end
@@ -1420,9 +1478,10 @@ module MarkdownExec
1420
1478
 
1421
1479
  def dml_menu_append_chrome_item(
1422
1480
  name, count, type,
1423
- id: '',
1481
+ always_create: true,
1482
+ always_enable: true,
1424
1483
  menu_state: MenuState::LOAD,
1425
- always_create: true, always_enable: true
1484
+ source_id: ''
1426
1485
  )
1427
1486
  raise unless name.present?
1428
1487
  raise if @dml_menu_blocks.nil?
@@ -1432,7 +1491,7 @@ module MarkdownExec
1432
1491
  # create menu item when it is needed (count > 0)
1433
1492
  #
1434
1493
  if item.nil? && (always_create || count.positive?)
1435
- item = append_chrome_block(id: id,
1494
+ item = append_chrome_block(source_id: source_id,
1436
1495
  menu_blocks: @dml_menu_blocks,
1437
1496
  menu_state: menu_state)
1438
1497
  end
@@ -1688,11 +1747,7 @@ module MarkdownExec
1688
1747
 
1689
1748
  elsif COLLAPSIBLE_TYPES.include?(selected.type)
1690
1749
  debounce_reset
1691
- if @compressed_ids.keys.include?(selected.id)
1692
- @compressed_ids.delete(selected.id)
1693
- else
1694
- @compressed_ids.merge!(selected.id => selected.level)
1695
- end
1750
+ menu_toggle_collapsible_block(selected)
1696
1751
  LoadFileLinkState.new(LoadFile::REUSE, link_state)
1697
1752
 
1698
1753
  elsif debounce_allows
@@ -1880,15 +1935,25 @@ module MarkdownExec
1880
1935
  view: @delegate_object[:vars_block_filename_view]
1881
1936
  )
1882
1937
  block_data = HashDelegator.parse_yaml_data_from_body(selected.body)
1883
- if selected_option = select_option_with_metadata(
1938
+
1939
+ dirs = Dir.glob(
1940
+ File.join(
1941
+ Dir.pwd,
1942
+ block_data['directory'] || directory,
1943
+ block_data['glob'] || glob
1944
+ )
1945
+ )
1946
+
1947
+ if !contains_glob?(block_data['directory']) &&
1948
+ !contains_glob?(block_data['glob'])
1949
+ if dirs[0]
1950
+ File.readlines(dirs[0], chomp: true)
1951
+ else
1952
+ warn 'No matching file found.'
1953
+ end
1954
+ elsif selected_option = select_option_with_metadata(
1884
1955
  prompt_title,
1885
- [exit_prompt] + Dir.glob(
1886
- File.join(
1887
- Dir.pwd,
1888
- block_data['directory'] || directory,
1889
- block_data['glob'] || glob
1890
- )
1891
- ).sort.map do |file|
1956
+ [exit_prompt] + dirs.sort.map do |file|
1892
1957
  { name: format(
1893
1958
  block_data['view'] || view,
1894
1959
  NamedCaptureExtractor.extract_named_group2(
@@ -1908,7 +1973,7 @@ module MarkdownExec
1908
1973
  File.readlines(selected_option.oname, chomp: true)
1909
1974
  end
1910
1975
  else
1911
- warn 'No matching files found'
1976
+ warn 'No matching files found.'
1912
1977
  end
1913
1978
  end
1914
1979
 
@@ -2175,6 +2240,7 @@ module MarkdownExec
2175
2240
  key_format: '${%s}',
2176
2241
  pattern: nil
2177
2242
  )
2243
+ # defined($x) ? '' : ($x = 1; pp [__LINE__, caller.deref])
2178
2244
  pattern ||= options_variable_expression_regexp
2179
2245
  return if pattern.nil?
2180
2246
 
@@ -2397,7 +2463,7 @@ module MarkdownExec
2397
2463
  Regexp.new(@delegate_object.fetch(
2398
2464
  :fenced_start_and_end_regex, '^(?<indent> *)`{3,}'
2399
2465
  )),
2400
- fcb: MarkdownExec::FCB.new,
2466
+ fcb: MarkdownExec::FCB.new(id: 'INIT'),
2401
2467
  in_fenced_block: false,
2402
2468
  headings: []
2403
2469
  }
@@ -2419,16 +2485,16 @@ module MarkdownExec
2419
2485
 
2420
2486
  update_line_and_block_state(
2421
2487
  nested_line, state, selected_types,
2422
- id: "#{@delegate_object[:filename]}:#{index}",
2488
+ source_id: "#{@delegate_object[:filename]}_ibfnf_#{index}",
2423
2489
  &block
2424
2490
  )
2425
2491
  end
2426
2492
  end
2427
2493
 
2428
- def iter_source_blocks(source, &block)
2494
+ def iter_source_blocks(source, source_id: nil, &block)
2429
2495
  case source
2430
2496
  when 1
2431
- blocks_from_nested_files.each(&block)
2497
+ blocks_from_nested_files(source_id: source_id).each(&block)
2432
2498
  when 2
2433
2499
  @dml_blocks_in_file.each(&block)
2434
2500
  when 3
@@ -2548,12 +2614,14 @@ module MarkdownExec
2548
2614
  }
2549
2615
  end
2550
2616
 
2551
- def list_blocks
2617
+ def list_blocks(source_id: nil)
2552
2618
  message = @delegate_object[:list_blocks_message]
2553
2619
  block_eval = @delegate_object[:list_blocks_eval]
2554
2620
 
2555
2621
  list = []
2556
- iter_source_blocks(@delegate_object[:list_blocks_type]) do |block|
2622
+ iter_source_blocks(
2623
+ @delegate_object[:list_blocks_type], source_id: source_id
2624
+ ) do |block|
2557
2625
  list << (block_eval.present? ? eval(block_eval) : block.send(message))
2558
2626
  end
2559
2627
  list.compact!
@@ -2566,7 +2634,7 @@ module MarkdownExec
2566
2634
  # Executes a specified block once per filename.
2567
2635
  # @param all_blocks [Array] Array of all block elements.
2568
2636
  # @return [Boolean, nil] True if values were modified, nil otherwise.
2569
- def load_auto_opts_block(all_blocks, id: '', mdoc:)
2637
+ def load_auto_opts_block(all_blocks, mdoc:)
2570
2638
  block_name = @delegate_object[:document_load_opts_block_name]
2571
2639
  unless block_name.present? &&
2572
2640
  @opts_most_recent_filename != @delegate_object[:filename]
@@ -2586,6 +2654,30 @@ module MarkdownExec
2586
2654
  true
2587
2655
  end
2588
2656
 
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
+
2589
2681
  def load_auto_vars_block(all_blocks,
2590
2682
  block_name: @delegate_object[:document_load_vars_block_name])
2591
2683
  unless block_name.present? &&
@@ -2628,7 +2720,7 @@ module MarkdownExec
2628
2720
  expanded_expression = formatted_expression(expression)
2629
2721
 
2630
2722
  # Handle wildcards or direct file specification
2631
- if contains_wildcards?(expanded_expression)
2723
+ if contains_glob?(expanded_expression)
2632
2724
  load_filespec_wildcard_expansion(expanded_expression)
2633
2725
  else
2634
2726
  expanded_expression
@@ -2676,8 +2768,8 @@ module MarkdownExec
2676
2768
  [block_name_from_cli, now_using_cli]
2677
2769
  end
2678
2770
 
2679
- def mdoc_and_blocks_from_nested_files
2680
- menu_blocks = blocks_from_nested_files
2771
+ def mdoc_and_blocks_from_nested_files(source_id: nil)
2772
+ menu_blocks = blocks_from_nested_files(source_id: source_id)
2681
2773
  mdoc = MDoc.new(menu_blocks) do |nopts|
2682
2774
  @delegate_object.merge!(nopts)
2683
2775
  end
@@ -2687,12 +2779,19 @@ module MarkdownExec
2687
2779
  ## Handles the file loading and returns the blocks
2688
2780
  # in the file and MDoc instance
2689
2781
  #
2690
- def mdoc_menu_and_blocks_from_nested_files(link_state, id: '')
2782
+ def mdoc_menu_and_blocks_from_nested_files(link_state, source_id: '')
2691
2783
  # read blocks, load document opts block, and re-process blocks
2692
2784
  #
2693
- all_blocks, mdoc = mdoc_and_blocks_from_nested_files
2694
- if load_auto_opts_block(all_blocks, id: id, mdoc: mdoc)
2695
- all_blocks, mdoc = mdoc_and_blocks_from_nested_files
2785
+ all_blocks, mdoc = mdoc_and_blocks_from_nested_files(source_id: source_id)
2786
+ if load_auto_opts_block(all_blocks, mdoc: mdoc)
2787
+ all_blocks, mdoc = mdoc_and_blocks_from_nested_files(source_id: source_id)
2788
+ end
2789
+
2790
+ # load document shell block
2791
+ #
2792
+ if code_lines = load_document_shell_block(all_blocks, mdoc: mdoc)
2793
+ next_state_set_code(nil, link_state, code_lines)
2794
+ link_state.inherited_lines = code_lines
2696
2795
  end
2697
2796
 
2698
2797
  # load document vars block
@@ -2700,11 +2799,7 @@ module MarkdownExec
2700
2799
  if code_lines = load_auto_vars_block(all_blocks)
2701
2800
  new_code = HashDelegator.code_merge(link_state.inherited_lines,
2702
2801
  code_lines)
2703
- next_state_set_code(
2704
- nil,
2705
- link_state,
2706
- new_code
2707
- )
2802
+ next_state_set_code(nil, link_state, new_code)
2708
2803
  link_state.inherited_lines = new_code
2709
2804
  end
2710
2805
 
@@ -2714,10 +2809,22 @@ module MarkdownExec
2714
2809
  @delegate_object.merge!(compressed_ids: @compressed_ids)
2715
2810
  )
2716
2811
 
2812
+ # re-expand blocks
2813
+ menu_blocks.each do |fcb|
2814
+ fcb.body = fcb.raw_body || fcb.body || []
2815
+ fcb.dname = fcb.raw_dname || fcb.dname
2816
+ fcb.s0printable = fcb.raw_s0printable || fcb.s0printable
2817
+ fcb.s1decorated = fcb.raw_s1decorated || fcb.s1decorated
2818
+ expand_references!(fcb, link_state)
2819
+ end
2820
+
2717
2821
  # chrome for menu
2718
2822
  #
2719
- add_menu_chrome_blocks!(id: id, menu_blocks: menu_blocks,
2720
- link_state: link_state)
2823
+ add_menu_chrome_blocks!(
2824
+ link_state: link_state,
2825
+ menu_blocks: menu_blocks,
2826
+ source_id: source_id
2827
+ )
2721
2828
 
2722
2829
  ### compress empty lines
2723
2830
  HashDelegator.delete_consecutive_blank_lines!(menu_blocks)
@@ -2743,6 +2850,7 @@ module MarkdownExec
2743
2850
  dname: HashDelegator.new(@delegate_object).string_send_color(
2744
2851
  document_glob, :menu_inherited_lines_color
2745
2852
  ),
2853
+ # 2025-01-03 menu item is disabled ∴ does not need a recall id
2746
2854
  oname: formatted_name
2747
2855
  )
2748
2856
 
@@ -2783,6 +2891,22 @@ module MarkdownExec
2783
2891
  end
2784
2892
  end
2785
2893
 
2894
+ def menu_compress_collapsible_block(selected)
2895
+ @compressed_ids.merge!(selected.id => selected.level)
2896
+ end
2897
+
2898
+ def menu_expand_collapsible_block(selected)
2899
+ @compressed_ids.delete(selected.id)
2900
+ end
2901
+
2902
+ def menu_toggle_collapsible_block(selected)
2903
+ if @compressed_ids.keys.include?(selected.id)
2904
+ menu_expand_collapsible_block(selected)
2905
+ else
2906
+ menu_compress_collapsible_block(selected)
2907
+ end
2908
+ end
2909
+
2786
2910
  # If a method is missing, treat it as a key for the @delegate_object.
2787
2911
  def method_missing(method_name, *args, &block)
2788
2912
  if @delegate_object.respond_to?(method_name)
@@ -3435,7 +3559,7 @@ module MarkdownExec
3435
3559
  formatted = formatted_expression(expression)
3436
3560
 
3437
3561
  # Handle wildcards or direct file specification
3438
- if contains_wildcards?(formatted)
3562
+ if contains_glob?(formatted)
3439
3563
  save_filespec_wildcard_expansion(formatted)
3440
3564
  else
3441
3565
  formatted
@@ -3579,11 +3703,14 @@ module MarkdownExec
3579
3703
  item == selection
3580
3704
  end
3581
3705
  end
3706
+
3707
+ # new FCB if selected is not an object
3582
3708
  if selected.instance_of?(String)
3583
3709
  selected = FCB.new(dname: selected)
3584
3710
  elsif selected.instance_of?(Hash)
3585
3711
  selected = FCB.new(selected)
3586
3712
  end
3713
+
3587
3714
  unless selected
3588
3715
  HashDelegator.error_handler('select_option_with_metadata',
3589
3716
  error: 'menu item not found')
@@ -3651,7 +3778,9 @@ module MarkdownExec
3651
3778
  # @param fenced_start_extended_regex [Regexp]
3652
3779
  # Regular expression to identify fenced block start.
3653
3780
  # @return [MarkdownExec::FCB] A new FCB instance with the parsed attributes.
3654
- def start_fenced_block(line, headings, fenced_start_extended_regex)
3781
+ def start_fenced_block(
3782
+ line, headings, fenced_start_extended_regex, source_id: nil
3783
+ )
3655
3784
  fcb_title_groups = NamedCaptureExtractor.extract_named_groups(
3656
3785
  line, fenced_start_extended_regex
3657
3786
  )
@@ -3702,6 +3831,7 @@ module MarkdownExec
3702
3831
  disabled: disabled,
3703
3832
  dname: dname,
3704
3833
  headings: headings,
3834
+ id: source_id.to_s,
3705
3835
  indent: fcb_title_groups.fetch(:indent, ''),
3706
3836
  nickname: nickname,
3707
3837
  oname: oname,
@@ -3764,7 +3894,7 @@ module MarkdownExec
3764
3894
  ##
3765
3895
  def update_line_and_block_state(
3766
3896
  nested_line, state, selected_types,
3767
- id:,
3897
+ source_id:,
3768
3898
  &block
3769
3899
  )
3770
3900
  line = nested_line.to_s
@@ -3784,7 +3914,8 @@ module MarkdownExec
3784
3914
  #
3785
3915
  state[:fcb] = start_fenced_block(
3786
3916
  line, state[:headings],
3787
- @delegate_object[:fenced_start_extended_regex]
3917
+ @delegate_object[:fenced_start_extended_regex],
3918
+ source_id: source_id
3788
3919
  )
3789
3920
  state[:fcb][:depth] = nested_line[:depth]
3790
3921
  state[:fcb][:indention] = nested_line[:indention]
@@ -3801,8 +3932,9 @@ module MarkdownExec
3801
3932
  @delegate_object[:menu_include_imported_notes]
3802
3933
  # add line if it is depth 0 or option allows it
3803
3934
  #
3804
- HashDelegator.yield_line_if_selected(line, selected_types, id: id,
3805
- &block)
3935
+ HashDelegator.yield_line_if_selected(
3936
+ line, selected_types, source_id: source_id, &block
3937
+ )
3806
3938
  end
3807
3939
  end
3808
3940
 
@@ -4078,15 +4210,20 @@ module MarkdownExec
4078
4210
  end
4079
4211
  end
4080
4212
 
4213
+ count = 0
4081
4214
  InputSequencer.new(
4082
4215
  @delegate_object[:filename],
4083
4216
  block_list
4084
4217
  ).run do |msg, data|
4218
+ count += 1
4085
4219
  case msg
4086
4220
  when :parse_document # once for each menu
4087
- vux_parse_document(id: 'vux_parse_document')
4088
- vux_menu_append_history_files(formatted_choice_ostructs,
4089
- id: 'vux_menu_append_history_files')
4221
+ count = 0
4222
+ vux_parse_document(source_id: "#{@delegate_object[:filename]}_vmlpd")
4223
+ vux_menu_append_history_files(
4224
+ formatted_choice_ostructs,
4225
+ source_id: "#{@delegate_object[:filename]}_vmlhf"
4226
+ )
4090
4227
  vux_publish_document_file_name_for_external_automation
4091
4228
 
4092
4229
  when :display_menu
@@ -4097,7 +4234,7 @@ module MarkdownExec
4097
4234
  # yield :end_of_cli, @delegate_object
4098
4235
 
4099
4236
  if @delegate_object[:list_blocks]
4100
- list_blocks
4237
+ list_blocks(source_id: "#{@delegate_object[:filename]}_vmleoc")
4101
4238
  :exit
4102
4239
  end
4103
4240
 
@@ -4132,8 +4269,9 @@ module MarkdownExec
4132
4269
  end
4133
4270
  end
4134
4271
 
4135
- def vux_menu_append_history_files(formatted_choice_ostructs,
4136
- id: '')
4272
+ def vux_menu_append_history_files(
4273
+ formatted_choice_ostructs, source_id: ''
4274
+ )
4137
4275
  if @delegate_object[:menu_for_history]
4138
4276
  history_files(
4139
4277
  @dml_link_state,
@@ -4145,8 +4283,8 @@ module MarkdownExec
4145
4283
  dml_menu_append_chrome_item(
4146
4284
  formatted_choice_ostructs[:history].oname, files.count,
4147
4285
  'files',
4148
- id: id,
4149
- menu_state: MenuState::HISTORY
4286
+ menu_state: MenuState::HISTORY,
4287
+ source_id: source_id
4150
4288
  )
4151
4289
  end
4152
4290
  end
@@ -4168,38 +4306,38 @@ module MarkdownExec
4168
4306
  if files.count.positive?
4169
4307
  dml_menu_append_chrome_item(
4170
4308
  formatted_choice_ostructs[:load].dname, files.count, 'files',
4171
- id: "#{id}.load",
4172
- menu_state: MenuState::LOAD
4309
+ menu_state: MenuState::LOAD,
4310
+ source_id: "#{source_id}_vmahf_load"
4173
4311
  )
4174
4312
  end
4175
4313
  if @delegate_object[:menu_inherited_lines_edit_always] ||
4176
4314
  lines_count.positive?
4177
4315
  dml_menu_append_chrome_item(
4178
4316
  formatted_choice_ostructs[:edit].dname, lines_count, 'lines',
4179
- id: "#{id}.edit",
4180
- menu_state: MenuState::EDIT
4317
+ menu_state: MenuState::EDIT,
4318
+ source_id: "#{source_id}_vmahf_edit"
4181
4319
  )
4182
4320
  end
4183
4321
  if lines_count.positive?
4184
4322
  dml_menu_append_chrome_item(
4185
4323
  formatted_choice_ostructs[:save].dname, 1, '',
4186
- id: "#{id}.save",
4187
- menu_state: MenuState::SAVE
4324
+ menu_state: MenuState::SAVE,
4325
+ source_id: "#{source_id}_vmahf_save"
4188
4326
  )
4189
4327
  end
4190
4328
  if lines_count.positive?
4191
4329
  dml_menu_append_chrome_item(
4192
4330
  formatted_choice_ostructs[:view].dname, 1, '',
4193
- id: "#{id}.view",
4194
- menu_state: MenuState::VIEW
4331
+ menu_state: MenuState::VIEW,
4332
+ source_id: "#{source_id}_vmahf_view"
4195
4333
  )
4196
4334
  end
4197
4335
  # rubocop:disable Style/GuardClause
4198
4336
  if @delegate_object[:menu_with_shell]
4199
4337
  dml_menu_append_chrome_item(
4200
4338
  formatted_choice_ostructs[:shell].dname, 1, '',
4201
- id: "#{id}.shell",
4202
- menu_state: MenuState::SHELL
4339
+ menu_state: MenuState::SHELL,
4340
+ source_id: "#{source_id}_vmahf_shell"
4203
4341
  )
4204
4342
  end
4205
4343
  # rubocop:enable Style/GuardClause
@@ -4217,7 +4355,7 @@ module MarkdownExec
4217
4355
  )
4218
4356
  end
4219
4357
 
4220
- def vux_parse_document(id: '')
4358
+ def vux_parse_document(source_id: '')
4221
4359
  @run_state.batch_index += 1
4222
4360
  @run_state.in_own_window = false
4223
4361
 
@@ -4239,7 +4377,9 @@ module MarkdownExec
4239
4377
  # update @delegate_object and @menu_base_options in auto_load
4240
4378
  #
4241
4379
  @dml_blocks_in_file, @dml_menu_blocks, @dml_mdoc =
4242
- mdoc_menu_and_blocks_from_nested_files(@dml_link_state, id: id)
4380
+ mdoc_menu_and_blocks_from_nested_files(
4381
+ @dml_link_state, source_id: source_id
4382
+ )
4243
4383
  dump_delobj(@dml_blocks_in_file, @dml_menu_blocks, @dml_link_state)
4244
4384
  end
4245
4385
 
@@ -94,13 +94,18 @@ class InputSequencer
94
94
  break if exit_when_bq_empty && bq_is_empty? && !now_menu.prior_block_was_link
95
95
 
96
96
  if now_menu.display_menu
97
+ # !!b
97
98
  break if run_yield(:end_of_cli, &block) == :exit
99
+ # !!b
98
100
 
99
101
  exit_when_bq_empty = false
100
102
  run_yield :display_menu, &block
103
+ # !!b
101
104
 
102
105
  choice = run_yield :user_choice, &block
106
+ # !!b
103
107
  break if choice == :break
108
+ # !!b
104
109
 
105
110
  raise BlockMissing, 'Block not recognized.' if choice.nil?
106
111
  # Exit loop and method to terminate the app
@@ -115,7 +120,9 @@ class InputSequencer
115
120
  if now_menu.block_name && !now_menu.block_name.empty?
116
121
  block_name = now_menu.block_name
117
122
  else
123
+ # break if bq_is_empty? # Exit loop if no more blocks to process
118
124
  if bq_is_empty? # Exit loop if no more blocks to process
125
+ # !!b
119
126
  run_yield :end_of_cli, &block
120
127
  break
121
128
  end
@@ -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.1'
10
+ VERSION = '2.7.2'
11
11
  end
data/lib/mdoc.rb CHANGED
@@ -177,12 +177,12 @@ module MarkdownExec
177
177
  blocks.map do |block|
178
178
  (block[:wraps] || []).map do |wrap|
179
179
  wrap_before = wrap.sub('}', '-before}') ### hardcoded wrap name
180
- @table.select { |fcb| [wrap_before, wrap].include? fcb.oname }
180
+ @table.select { |fcb| fcb.code_name_included?(wrap_before, wrap) }
181
181
  end.flatten(1) +
182
182
  [block] +
183
183
  (block[:wraps] || []).reverse.map do |wrap|
184
184
  wrap_after = wrap.sub('}', '-after}') ### hardcoded wrap name
185
- @table.select { |fcb| fcb.oname == wrap_after }
185
+ @table.select { |fcb| fcb.code_name_included?(wrap_after) }
186
186
  end.flatten(1)
187
187
  end.flatten(1).compact
188
188
  end
@@ -623,25 +623,22 @@ if $PROGRAM_NAME == __FILE__
623
623
  # Mocking the @table object for testing
624
624
  def setup
625
625
  @table = [
626
- OpenStruct.new(oname: '{wrap1}'),
627
- OpenStruct.new(oname: '{wrap2-before}'),
628
- OpenStruct.new(oname: '{wrap2}'),
629
- OpenStruct.new(oname: '{wrap2-after}'),
630
- OpenStruct.new(oname: '{wrap3-before}'),
631
- OpenStruct.new(oname: '{wrap3}'),
632
- OpenStruct.new(oname: '{wrap3-after}')
626
+ FCB.new(oname: '{wrap1}'),
627
+ FCB.new(oname: '{wrap2-before}'),
628
+ FCB.new(oname: '{wrap2}'),
629
+ FCB.new(oname: '{wrap2-after}'),
630
+ FCB.new(oname: '{wrap3-before}'),
631
+ FCB.new(oname: '{wrap3}'),
632
+ FCB.new(oname: '{wrap3-after}')
633
633
  ]
634
634
  @mdoc = MDoc.new(@table)
635
635
  end
636
636
 
637
637
  def test_collect_wrapped_blocks
638
638
  # Test case 1: blocks with wraps
639
- OpenStruct.new(oname: 'block1')
640
-
641
639
  assert_equal(%w[{wrap2-before} {wrap2} b {wrap2-after}],
642
640
  @mdoc.collect_wrapped_blocks(
643
- [OpenStruct.new(oname: 'b',
644
- wraps: ['{wrap2}'])]
641
+ [FCB.new(oname: 'b', wraps: ['{wrap2}'])]
645
642
  ).map(&:oname))
646
643
 
647
644
  assert_equal(%w[{wrap2-before} {wrap2} {wrap3-before} {wrap3} c {wrap3-after} {wrap2-after}],
data/lib/menu.src.yml CHANGED
@@ -200,6 +200,12 @@
200
200
  :default: "(document_opts)"
201
201
  :procname: val_as_str
202
202
 
203
+ - :opt_name: document_load_shell_block_name
204
+ :env_var: MDE_DOCUMENT_LOAD_SHELL_BLOCK_NAME
205
+ :description: Name of shell block to load with the document
206
+ :default: "(document_shell)"
207
+ :procname: val_as_str
208
+
203
209
  - :opt_name: document_load_vars_block_name
204
210
  :env_var: MDE_DOCUMENT_LOAD_VARS_BLOCK_NAME
205
211
  :description: Name of Vars block to load with the document
@@ -676,8 +682,7 @@
676
682
  :env_var: MDE_MENU_ACTIVE_COLOR_PASTEL_MESSAGES
677
683
  :description: menu_active_color_pastel_messages
678
684
  :default:
679
- - bright_magenta
680
- - on_black
685
+ - inverse
681
686
 
682
687
  - :opt_name: menu_back_at_top
683
688
  :env_var: MDE_MENU_BACK_AT_TOP
data/lib/menu.yml CHANGED
@@ -166,6 +166,11 @@
166
166
  :description: Name of Opts block to load with the document
167
167
  :default: "(document_opts)"
168
168
  :procname: val_as_str
169
+ - :opt_name: document_load_shell_block_name
170
+ :env_var: MDE_DOCUMENT_LOAD_SHELL_BLOCK_NAME
171
+ :description: Name of shell block to load with the document
172
+ :default: "(document_shell)"
173
+ :procname: val_as_str
169
174
  - :opt_name: document_load_vars_block_name
170
175
  :env_var: MDE_DOCUMENT_LOAD_VARS_BLOCK_NAME
171
176
  :description: Name of Vars block to load with the document
@@ -572,8 +577,7 @@
572
577
  :env_var: MDE_MENU_ACTIVE_COLOR_PASTEL_MESSAGES
573
578
  :description: menu_active_color_pastel_messages
574
579
  :default:
575
- - bright_magenta
576
- - on_black
580
+ - inverse
577
581
  - :opt_name: menu_back_at_top
578
582
  :env_var: MDE_MENU_BACK_AT_TOP
579
583
  :description: Display Back option at top of menu (vs bottom)
data/lib/ww.rb CHANGED
@@ -24,7 +24,7 @@ def ww0(*objs,
24
24
  category: nil,
25
25
  full_backtrace: false,
26
26
  level: :debug,
27
- locations: caller_locations,
27
+ locations: caller_locations[1..-1],
28
28
  log_file: nil,
29
29
  output: $stderr,
30
30
  single_line: false,
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.1
4
+ version: 2.7.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fareed Stevenson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-10 00:00:00.000000000 Z
11
+ date: 2025-01-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -108,8 +108,10 @@ files:
108
108
  - assets/select_a_file.png
109
109
  - bats/bats.bats
110
110
  - bats/block-types.bats
111
+ - bats/border.bats
111
112
  - bats/cli.bats
112
113
  - bats/command-substitution.bats
114
+ - bats/document-shell.bats
113
115
  - bats/fail.bats
114
116
  - bats/history.bats
115
117
  - bats/import.bats
@@ -134,9 +136,11 @@ files:
134
136
  - docs/dev/block-type-opts.md
135
137
  - docs/dev/block-type-port.md
136
138
  - docs/dev/block-type-vars.md
139
+ - docs/dev/border.md
137
140
  - docs/dev/command-substitution.md
138
141
  - docs/dev/data-blocks.md
139
142
  - docs/dev/disable.md
143
+ - docs/dev/document-shell.md
140
144
  - docs/dev/import-missing.md
141
145
  - docs/dev/import.md
142
146
  - docs/dev/linked-file.md