markdown_exec 2.7.1 → 2.7.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +33 -1
- data/Gemfile.lock +1 -1
- data/Rakefile +29 -11
- data/bats/block-type-opts.bats +23 -0
- data/bats/block-type-vars.bats +26 -0
- data/bats/block-types.bats +0 -36
- data/bats/border.bats +8 -0
- data/bats/document-shell.bats +9 -0
- data/bats/line-wrapping.bats +8 -0
- data/bin/tab_completion.sh +1 -1
- data/docs/dev/block-type-opts.md +4 -1
- data/docs/dev/block-type-vars.md +15 -4
- data/docs/dev/border.md +7 -0
- data/docs/dev/command-substitution.md +1 -0
- data/docs/dev/document-shell.md +6 -0
- data/docs/dev/line-wrapping.md +24 -0
- data/examples/link-blocks-vars.md +69 -41
- data/lib/colorize.rb +11 -37
- data/lib/fcb.rb +16 -4
- data/lib/filter.rb +3 -24
- data/lib/format_table.rb +0 -1
- data/lib/hash_delegator.rb +340 -173
- data/lib/input_sequencer.rb +7 -0
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +1 -2
- data/lib/mdoc.rb +10 -13
- data/lib/menu.src.yml +8 -4
- data/lib/menu.yml +7 -3
- data/lib/ww.rb +4 -2
- metadata +11 -3
- /data/examples/{wrap.md → wrapped-blocks.md} +0 -0
data/lib/hash_delegator.rb
CHANGED
@@ -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
|
@@ -361,10 +365,10 @@ module HashDelegatorSelf
|
|
361
365
|
# @param [String] line The line to be processed.
|
362
366
|
# @param [Array<Symbol>] selected_types A list of message types to check.
|
363
367
|
# @param [Proc] block The block to be called with the line data.
|
364
|
-
def yield_line_if_selected(line, selected_types,
|
368
|
+
def yield_line_if_selected(line, selected_types, source_id: '', &block)
|
365
369
|
return unless block && block_type_selected?(selected_types, :line)
|
366
370
|
|
367
|
-
block.call(:line, MarkdownExec::FCB.new(body: [line], id:
|
371
|
+
block.call(:line, MarkdownExec::FCB.new(body: [line], id: source_id))
|
368
372
|
end
|
369
373
|
end
|
370
374
|
|
@@ -600,52 +604,72 @@ module MarkdownExec
|
|
600
604
|
end
|
601
605
|
end
|
602
606
|
|
603
|
-
def add_back_option(
|
604
|
-
append_chrome_block(
|
605
|
-
|
607
|
+
def add_back_option(menu_blocks:, source_id: '')
|
608
|
+
append_chrome_block(
|
609
|
+
menu_blocks: menu_blocks,
|
610
|
+
menu_state: MenuState::BACK,
|
611
|
+
source_id: source_id
|
612
|
+
)
|
606
613
|
end
|
607
614
|
|
608
|
-
def add_exit_option(
|
609
|
-
append_chrome_block(
|
610
|
-
|
615
|
+
def add_exit_option(menu_blocks:, source_id: '')
|
616
|
+
append_chrome_block(
|
617
|
+
menu_blocks: menu_blocks,
|
618
|
+
menu_state: MenuState::EXIT,
|
619
|
+
source_id: source_id
|
620
|
+
)
|
611
621
|
end
|
612
622
|
|
613
|
-
def add_inherited_lines(
|
614
|
-
append_inherited_lines(
|
623
|
+
def add_inherited_lines(link_state:, menu_blocks:)
|
624
|
+
append_inherited_lines(
|
625
|
+
link_state: link_state,
|
626
|
+
menu_blocks: menu_blocks
|
627
|
+
)
|
615
628
|
end
|
616
629
|
|
617
630
|
# Modifies the provided menu blocks array by adding 'Back' and 'Exit' options,
|
618
631
|
# along with initial and final dividers, based on the delegate object's configuration.
|
619
632
|
#
|
620
633
|
# @param menu_blocks [Array] The array of menu block elements to be modified.
|
621
|
-
def add_menu_chrome_blocks!(
|
634
|
+
def add_menu_chrome_blocks!(link_state:, menu_blocks:, source_id: '')
|
622
635
|
return unless @delegate_object[:menu_link_format].present?
|
623
636
|
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
637
|
+
add_inherited_lines(
|
638
|
+
link_state: link_state,
|
639
|
+
menu_blocks: menu_blocks
|
640
|
+
) if @delegate_object[:menu_with_inherited_lines]
|
628
641
|
|
629
642
|
# back before exit
|
630
|
-
add_back_option(
|
631
|
-
|
643
|
+
add_back_option(
|
644
|
+
menu_blocks: menu_blocks,
|
645
|
+
source_id: "#{source_id}.back"
|
646
|
+
) if should_add_back_option?
|
632
647
|
|
633
648
|
# 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
649
|
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
650
|
+
add_exit_option(
|
651
|
+
menu_blocks: menu_blocks,
|
652
|
+
source_id: "#{source_id}.exit"
|
653
|
+
) if @delegate_object[:menu_with_exit]
|
654
|
+
|
655
|
+
append_divider(
|
656
|
+
menu_blocks: menu_blocks,
|
657
|
+
position: :initial,
|
658
|
+
source_id: "#{source_id}.init"
|
659
|
+
)
|
660
|
+
|
661
|
+
append_divider(
|
662
|
+
menu_blocks: menu_blocks,
|
663
|
+
position: :final,
|
664
|
+
source_id: "#{source_id}.final"
|
665
|
+
)
|
642
666
|
end
|
643
667
|
|
644
668
|
# Appends a chrome block, which is a menu option for Back or Exit
|
645
669
|
#
|
646
670
|
# @param all_blocks [Array] The current blocks in the menu
|
647
671
|
# @param type [Symbol] The type of chrome block to add (:back or :exit)
|
648
|
-
def append_chrome_block(menu_blocks:, menu_state:,
|
672
|
+
def append_chrome_block(menu_blocks:, menu_state:, source_id: '')
|
649
673
|
case menu_state
|
650
674
|
when MenuState::BACK
|
651
675
|
history_state_partition
|
@@ -683,7 +707,7 @@ module MarkdownExec
|
|
683
707
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
684
708
|
formatted_name, :menu_chrome_color
|
685
709
|
),
|
686
|
-
id:
|
710
|
+
id: source_id.to_s,
|
687
711
|
type: BlockType::CHROME,
|
688
712
|
nickname: formatted_name,
|
689
713
|
oname: formatted_name
|
@@ -703,10 +727,10 @@ module MarkdownExec
|
|
703
727
|
#
|
704
728
|
# @param menu_blocks [Array] The array of menu block elements.
|
705
729
|
# @param position [Symbol] The position to insert the divider (:initial or :final).
|
706
|
-
def append_divider(
|
730
|
+
def append_divider(menu_blocks:, position:, source_id: '')
|
707
731
|
return unless divider_formatting_present?(position)
|
708
732
|
|
709
|
-
divider = create_divider(position,
|
733
|
+
divider = create_divider(position, source_id: source_id)
|
710
734
|
position == :initial ? menu_blocks.unshift(divider) : menu_blocks.push(divider)
|
711
735
|
end
|
712
736
|
|
@@ -715,7 +739,7 @@ module MarkdownExec
|
|
715
739
|
#
|
716
740
|
# @param menu_blocks [Array] The array of menu block elements.
|
717
741
|
# @param position [Symbol] The position to insert the divider (:initial or :final).
|
718
|
-
def append_inherited_lines(
|
742
|
+
def append_inherited_lines(link_state:, menu_blocks:, position: top)
|
719
743
|
return unless link_state.inherited_lines_present?
|
720
744
|
|
721
745
|
insert_at_top = @delegate_object[:menu_inherited_lines_at_top]
|
@@ -783,13 +807,31 @@ module MarkdownExec
|
|
783
807
|
|
784
808
|
# private
|
785
809
|
|
810
|
+
def expand_references!(fcb, link_state)
|
811
|
+
expand_variable_references!(
|
812
|
+
blocks: [fcb],
|
813
|
+
initial_code_required: false,
|
814
|
+
link_state: link_state
|
815
|
+
)
|
816
|
+
expand_variable_references!(
|
817
|
+
blocks: [fcb],
|
818
|
+
echo_format: '%s',
|
819
|
+
group_name: :command,
|
820
|
+
initial_code_required: false,
|
821
|
+
key_format: '$(%s)',
|
822
|
+
link_state: link_state,
|
823
|
+
pattern: options_command_substitution_regexp
|
824
|
+
)
|
825
|
+
end
|
826
|
+
|
786
827
|
# Iterates through nested files to collect various types
|
787
828
|
# of blocks, including dividers, tasks, and others.
|
788
829
|
# The method categorizes blocks based on their type and processes them accordingly.
|
789
830
|
#
|
790
831
|
# @return [Array<FCB>] An array of FCB objects representing the blocks.
|
791
832
|
def blocks_from_nested_files(
|
792
|
-
link_state: @dml_link_state || LinkState.new
|
833
|
+
link_state: @dml_link_state || LinkState.new,
|
834
|
+
source_id: nil
|
793
835
|
)
|
794
836
|
register_console_attributes(@delegate_object)
|
795
837
|
@decor_patterns_from_delegate_object_for_block_create = collect_line_decor_patterns(@delegate_object)
|
@@ -799,22 +841,6 @@ module MarkdownExec
|
|
799
841
|
iter_blocks_from_nested_files do |btype, fcb|
|
800
842
|
count += 1
|
801
843
|
|
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
844
|
case btype
|
819
845
|
when :blocks
|
820
846
|
if @delegate_object[:bash]
|
@@ -822,20 +848,25 @@ module MarkdownExec
|
|
822
848
|
block_calls_scan: @delegate_object[:block_calls_scan],
|
823
849
|
block_name_match: @delegate_object[:block_name_match],
|
824
850
|
block_name_nick_match: @delegate_object[:block_name_nick_match],
|
825
|
-
id: "
|
851
|
+
id: "#{source_id}_bfnf_b_#{count}"
|
826
852
|
) do |oname, color|
|
827
853
|
apply_block_type_color_option(oname, color)
|
828
854
|
end
|
855
|
+
else
|
856
|
+
expand_references!(fcb, link_state)
|
829
857
|
end
|
830
|
-
expand_references.call(fcb)
|
831
858
|
blocks << fcb
|
832
859
|
when :filter # types accepted
|
833
860
|
%i[blocks line]
|
834
861
|
when :line
|
835
862
|
unless @delegate_object[:no_chrome]
|
836
|
-
|
837
|
-
create_and_add_chrome_blocks(
|
838
|
-
|
863
|
+
# expand references only if block is recognized (not a comment)
|
864
|
+
create_and_add_chrome_blocks(
|
865
|
+
blocks, fcb, id: "#{source_id}_bfnf_l_#{count}", init_ids: init_ids
|
866
|
+
) do
|
867
|
+
# expand references only if block is recognized (not a comment)
|
868
|
+
expand_references!(fcb, link_state)
|
869
|
+
end
|
839
870
|
end
|
840
871
|
end
|
841
872
|
end
|
@@ -952,16 +983,19 @@ module MarkdownExec
|
|
952
983
|
|
953
984
|
# sets ENV
|
954
985
|
def code_from_vars_block_to_set_environment_variables(selected)
|
955
|
-
code_lines = []
|
956
|
-
YAML.load(selected.body.join("\n"))
|
957
|
-
|
958
|
-
|
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)}"
|
959
992
|
|
960
|
-
|
993
|
+
next unless @delegate_object[:menu_vars_set_format].present?
|
961
994
|
|
962
|
-
|
963
|
-
|
964
|
-
|
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
|
965
999
|
end
|
966
1000
|
code_lines
|
967
1001
|
end
|
@@ -1134,8 +1168,10 @@ module MarkdownExec
|
|
1134
1168
|
end
|
1135
1169
|
|
1136
1170
|
# Check if the expression contains wildcard characters
|
1137
|
-
def
|
1138
|
-
|
1171
|
+
def contains_glob?(str)
|
1172
|
+
return false if str.nil?
|
1173
|
+
|
1174
|
+
str.match?(/[\*\?\[\{\}]/)
|
1139
1175
|
end
|
1140
1176
|
|
1141
1177
|
def copy_to_clipboard(required_lines)
|
@@ -1200,13 +1236,15 @@ module MarkdownExec
|
|
1200
1236
|
collapse: nil, color_method:, decor_patterns: [],
|
1201
1237
|
disabled: true, format_option:, id: '',
|
1202
1238
|
level: 0, match_data:, type: '',
|
1203
|
-
wrap: nil
|
1239
|
+
wrap: nil,
|
1240
|
+
fcb: nil
|
1204
1241
|
)
|
1205
|
-
|
1242
|
+
ww 'match_data', match_data
|
1243
|
+
line_cap = NamedCaptureExtractor.extract_named_group_match_data(match_data)
|
1206
1244
|
# replace tabs in indent
|
1207
1245
|
line_cap[:indent] ||= ''
|
1208
1246
|
line_cap[:indent] = line_cap[:indent].dup if line_cap[:indent].frozen?
|
1209
|
-
line_cap[:indent].gsub!("\t", ' ')
|
1247
|
+
line_cap[:indent].gsub!("\t", ' ') # TAB_SIZE = 4
|
1210
1248
|
# replace tabs in text
|
1211
1249
|
line_cap[:text] ||= ''
|
1212
1250
|
line_cap[:text] = line_cap[:text].dup if line_cap[:text].frozen?
|
@@ -1234,6 +1272,7 @@ module MarkdownExec
|
|
1234
1272
|
end
|
1235
1273
|
end
|
1236
1274
|
|
1275
|
+
use_fcb = !fcb.nil? # fcb only for the first record if any
|
1237
1276
|
line_caps.each_with_index do |line_obj, index|
|
1238
1277
|
next if line_obj[:text].nil?
|
1239
1278
|
|
@@ -1256,23 +1295,45 @@ module MarkdownExec
|
|
1256
1295
|
)
|
1257
1296
|
|
1258
1297
|
line_obj[:line] = line_obj[:indent] + line_obj[:text]
|
1259
|
-
|
1260
|
-
|
1261
|
-
|
1262
|
-
|
1263
|
-
|
1264
|
-
|
1265
|
-
|
1266
|
-
|
1267
|
-
|
1268
|
-
|
1269
|
-
|
1270
|
-
|
1271
|
-
|
1272
|
-
|
1273
|
-
|
1274
|
-
|
1275
|
-
|
1298
|
+
|
1299
|
+
if !use_fcb
|
1300
|
+
fcb = FCB.new(
|
1301
|
+
center: center,
|
1302
|
+
chrome: true,
|
1303
|
+
collapse: collapse.nil? ? (line_obj[:collapse] == COLLAPSIBLE_TOKEN_COLLAPSE) : collapse,
|
1304
|
+
token: line_obj[:collapse],
|
1305
|
+
disabled: disabled ? TtyMenu::DISABLE : nil,
|
1306
|
+
id: "#{id}.#{index}",
|
1307
|
+
level: level,
|
1308
|
+
s0indent: indent,
|
1309
|
+
s0printable: line_obj[:text],
|
1310
|
+
s1decorated: decorated,
|
1311
|
+
dname: line_obj[:indent] + decorated,
|
1312
|
+
indent: line_obj[:indent],
|
1313
|
+
oname: line_obj[:text],
|
1314
|
+
text: line_obj[:text],
|
1315
|
+
type: type
|
1316
|
+
)
|
1317
|
+
else
|
1318
|
+
fcb.center = center
|
1319
|
+
fcb.chrome = true
|
1320
|
+
fcb.collapse = collapse.nil? ? (line_obj[:collapse] == COLLAPSIBLE_TOKEN_COLLAPSE) : collapse
|
1321
|
+
fcb.token = line_obj[:collapse]
|
1322
|
+
fcb.disabled = disabled ? TtyMenu::DISABLE : nil
|
1323
|
+
fcb.id = "#{id}.#{index}"
|
1324
|
+
fcb.level = level
|
1325
|
+
fcb.s0indent = indent
|
1326
|
+
fcb.s0printable = line_obj[:text]
|
1327
|
+
fcb.s1decorated = decorated
|
1328
|
+
fcb.dname = line_obj[:indent] + decorated
|
1329
|
+
fcb.indent = line_obj[:indent]
|
1330
|
+
fcb.oname = line_obj[:text]
|
1331
|
+
fcb.text = line_obj[:text]
|
1332
|
+
fcb.type = type
|
1333
|
+
use_fcb = false # next line is new record
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
blocks.push fcb
|
1276
1337
|
end
|
1277
1338
|
line_caps.count
|
1278
1339
|
end
|
@@ -1292,6 +1353,12 @@ module MarkdownExec
|
|
1292
1353
|
next
|
1293
1354
|
end
|
1294
1355
|
|
1356
|
+
if block_given?
|
1357
|
+
# expand references only if block is recognized (not a comment)
|
1358
|
+
yield if block_given?
|
1359
|
+
mbody = fcb.body[0].match @delegate_object[criteria[:match]]
|
1360
|
+
end
|
1361
|
+
|
1295
1362
|
create_and_add_chrome_block(
|
1296
1363
|
blocks: blocks,
|
1297
1364
|
case_conversion: criteria[:case_conversion],
|
@@ -1312,6 +1379,7 @@ module MarkdownExec
|
|
1312
1379
|
decor_patterns:
|
1313
1380
|
@decor_patterns_from_delegate_object_for_block_create,
|
1314
1381
|
disabled: !(criteria[:collapsible] && @delegate_object[criteria[:collapsible]]),
|
1382
|
+
fcb: fcb,
|
1315
1383
|
id: "#{id}.#{index}",
|
1316
1384
|
format_option: criteria[:format] &&
|
1317
1385
|
@delegate_object[criteria[:format]],
|
@@ -1324,7 +1392,7 @@ module MarkdownExec
|
|
1324
1392
|
end
|
1325
1393
|
end
|
1326
1394
|
|
1327
|
-
def create_divider(position,
|
1395
|
+
def create_divider(position, source_id: '')
|
1328
1396
|
divider_key = if position == :initial
|
1329
1397
|
:menu_initial_divider
|
1330
1398
|
else
|
@@ -1337,7 +1405,7 @@ module MarkdownExec
|
|
1337
1405
|
chrome: true,
|
1338
1406
|
disabled: TtyMenu::DISABLE,
|
1339
1407
|
dname: string_send_color(oname, :menu_divider_color),
|
1340
|
-
id:
|
1408
|
+
id: source_id,
|
1341
1409
|
oname: oname
|
1342
1410
|
)
|
1343
1411
|
end
|
@@ -1420,9 +1488,10 @@ module MarkdownExec
|
|
1420
1488
|
|
1421
1489
|
def dml_menu_append_chrome_item(
|
1422
1490
|
name, count, type,
|
1423
|
-
|
1491
|
+
always_create: true,
|
1492
|
+
always_enable: true,
|
1424
1493
|
menu_state: MenuState::LOAD,
|
1425
|
-
|
1494
|
+
source_id: ''
|
1426
1495
|
)
|
1427
1496
|
raise unless name.present?
|
1428
1497
|
raise if @dml_menu_blocks.nil?
|
@@ -1432,7 +1501,7 @@ module MarkdownExec
|
|
1432
1501
|
# create menu item when it is needed (count > 0)
|
1433
1502
|
#
|
1434
1503
|
if item.nil? && (always_create || count.positive?)
|
1435
|
-
item = append_chrome_block(
|
1504
|
+
item = append_chrome_block(source_id: source_id,
|
1436
1505
|
menu_blocks: @dml_menu_blocks,
|
1437
1506
|
menu_state: menu_state)
|
1438
1507
|
end
|
@@ -1688,11 +1757,7 @@ module MarkdownExec
|
|
1688
1757
|
|
1689
1758
|
elsif COLLAPSIBLE_TYPES.include?(selected.type)
|
1690
1759
|
debounce_reset
|
1691
|
-
|
1692
|
-
@compressed_ids.delete(selected.id)
|
1693
|
-
else
|
1694
|
-
@compressed_ids.merge!(selected.id => selected.level)
|
1695
|
-
end
|
1760
|
+
menu_toggle_collapsible_block(selected)
|
1696
1761
|
LoadFileLinkState.new(LoadFile::REUSE, link_state)
|
1697
1762
|
|
1698
1763
|
elsif debounce_allows
|
@@ -1880,18 +1945,28 @@ module MarkdownExec
|
|
1880
1945
|
view: @delegate_object[:vars_block_filename_view]
|
1881
1946
|
)
|
1882
1947
|
block_data = HashDelegator.parse_yaml_data_from_body(selected.body)
|
1883
|
-
|
1948
|
+
|
1949
|
+
dirs = Dir.glob(
|
1950
|
+
File.join(
|
1951
|
+
Dir.pwd,
|
1952
|
+
block_data['directory'] || directory,
|
1953
|
+
block_data['glob'] || glob
|
1954
|
+
)
|
1955
|
+
)
|
1956
|
+
|
1957
|
+
if !contains_glob?(block_data['directory']) &&
|
1958
|
+
!contains_glob?(block_data['glob'])
|
1959
|
+
if dirs[0]
|
1960
|
+
File.readlines(dirs[0], chomp: true)
|
1961
|
+
else
|
1962
|
+
warn 'No matching file found.'
|
1963
|
+
end
|
1964
|
+
elsif selected_option = select_option_with_metadata(
|
1884
1965
|
prompt_title,
|
1885
|
-
[exit_prompt] +
|
1886
|
-
File.join(
|
1887
|
-
Dir.pwd,
|
1888
|
-
block_data['directory'] || directory,
|
1889
|
-
block_data['glob'] || glob
|
1890
|
-
)
|
1891
|
-
).sort.map do |file|
|
1966
|
+
[exit_prompt] + dirs.sort.map do |file|
|
1892
1967
|
{ name: format(
|
1893
1968
|
block_data['view'] || view,
|
1894
|
-
NamedCaptureExtractor.
|
1969
|
+
NamedCaptureExtractor.extract_named_group_match_data(
|
1895
1970
|
file.match(
|
1896
1971
|
Regexp.new(block_data['filename_pattern'] ||
|
1897
1972
|
filename_pattern)
|
@@ -1908,7 +1983,7 @@ module MarkdownExec
|
|
1908
1983
|
File.readlines(selected_option.oname, chomp: true)
|
1909
1984
|
end
|
1910
1985
|
else
|
1911
|
-
warn 'No matching files found'
|
1986
|
+
warn 'No matching files found.'
|
1912
1987
|
end
|
1913
1988
|
end
|
1914
1989
|
|
@@ -2397,7 +2472,7 @@ module MarkdownExec
|
|
2397
2472
|
Regexp.new(@delegate_object.fetch(
|
2398
2473
|
:fenced_start_and_end_regex, '^(?<indent> *)`{3,}'
|
2399
2474
|
)),
|
2400
|
-
fcb: MarkdownExec::FCB.new,
|
2475
|
+
fcb: MarkdownExec::FCB.new(id: 'INIT'),
|
2401
2476
|
in_fenced_block: false,
|
2402
2477
|
headings: []
|
2403
2478
|
}
|
@@ -2419,16 +2494,16 @@ module MarkdownExec
|
|
2419
2494
|
|
2420
2495
|
update_line_and_block_state(
|
2421
2496
|
nested_line, state, selected_types,
|
2422
|
-
|
2497
|
+
source_id: "#{@delegate_object[:filename]}_ibfnf_#{index}",
|
2423
2498
|
&block
|
2424
2499
|
)
|
2425
2500
|
end
|
2426
2501
|
end
|
2427
2502
|
|
2428
|
-
def iter_source_blocks(source, &block)
|
2503
|
+
def iter_source_blocks(source, source_id: nil, &block)
|
2429
2504
|
case source
|
2430
2505
|
when 1
|
2431
|
-
blocks_from_nested_files.each(&block)
|
2506
|
+
blocks_from_nested_files(source_id: source_id).each(&block)
|
2432
2507
|
when 2
|
2433
2508
|
@dml_blocks_in_file.each(&block)
|
2434
2509
|
when 3
|
@@ -2487,20 +2562,29 @@ module MarkdownExec
|
|
2487
2562
|
label_format_above = @delegate_object[:shell_code_label_format_above]
|
2488
2563
|
label_format_below = @delegate_object[:shell_code_label_format_below]
|
2489
2564
|
|
2490
|
-
[
|
2491
|
-
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
2499
|
-
|
2500
|
-
|
2501
|
-
|
2502
|
-
|
2503
|
-
|
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
|
2504
2588
|
end
|
2505
2589
|
|
2506
2590
|
def link_history_push_and_next(
|
@@ -2548,12 +2632,14 @@ module MarkdownExec
|
|
2548
2632
|
}
|
2549
2633
|
end
|
2550
2634
|
|
2551
|
-
def list_blocks
|
2635
|
+
def list_blocks(source_id: nil)
|
2552
2636
|
message = @delegate_object[:list_blocks_message]
|
2553
2637
|
block_eval = @delegate_object[:list_blocks_eval]
|
2554
2638
|
|
2555
2639
|
list = []
|
2556
|
-
iter_source_blocks(
|
2640
|
+
iter_source_blocks(
|
2641
|
+
@delegate_object[:list_blocks_type], source_id: source_id
|
2642
|
+
) do |block|
|
2557
2643
|
list << (block_eval.present? ? eval(block_eval) : block.send(message))
|
2558
2644
|
end
|
2559
2645
|
list.compact!
|
@@ -2566,21 +2652,25 @@ module MarkdownExec
|
|
2566
2652
|
# Executes a specified block once per filename.
|
2567
2653
|
# @param all_blocks [Array] Array of all block elements.
|
2568
2654
|
# @return [Boolean, nil] True if values were modified, nil otherwise.
|
2569
|
-
def load_auto_opts_block(all_blocks,
|
2655
|
+
def load_auto_opts_block(all_blocks, mdoc:)
|
2570
2656
|
block_name = @delegate_object[:document_load_opts_block_name]
|
2571
2657
|
unless block_name.present? &&
|
2572
2658
|
@opts_most_recent_filename != @delegate_object[:filename]
|
2573
2659
|
return
|
2574
2660
|
end
|
2575
2661
|
|
2576
|
-
|
2577
|
-
return
|
2662
|
+
blocks = HashDelegator.block_select(all_blocks, :oname, block_name)
|
2663
|
+
return if blocks.empty?
|
2578
2664
|
|
2579
|
-
|
2580
|
-
|
2581
|
-
|
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
|
2582
2673
|
)
|
2583
|
-
update_menu_base(options_state.options)
|
2584
2674
|
|
2585
2675
|
@opts_most_recent_filename = @delegate_object[:filename]
|
2586
2676
|
true
|
@@ -2593,11 +2683,16 @@ module MarkdownExec
|
|
2593
2683
|
return
|
2594
2684
|
end
|
2595
2685
|
|
2596
|
-
|
2597
|
-
return
|
2686
|
+
blocks = HashDelegator.block_select(all_blocks, :oname, block_name)
|
2687
|
+
return if blocks.empty?
|
2598
2688
|
|
2599
2689
|
@vars_most_recent_filename = @delegate_object[:filename]
|
2600
|
-
|
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
|
2601
2696
|
end
|
2602
2697
|
|
2603
2698
|
def load_cli_or_user_selected_block(all_blocks: [], menu_blocks: [],
|
@@ -2620,6 +2715,30 @@ module MarkdownExec
|
|
2620
2715
|
SelectedBlockMenuState.new(block, source, state)
|
2621
2716
|
end
|
2622
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
|
+
|
2623
2742
|
# format + glob + select for file in load block
|
2624
2743
|
# name has references to ENV vars and doc and batch vars
|
2625
2744
|
# incl. timestamp
|
@@ -2628,7 +2747,7 @@ module MarkdownExec
|
|
2628
2747
|
expanded_expression = formatted_expression(expression)
|
2629
2748
|
|
2630
2749
|
# Handle wildcards or direct file specification
|
2631
|
-
if
|
2750
|
+
if contains_glob?(expanded_expression)
|
2632
2751
|
load_filespec_wildcard_expansion(expanded_expression)
|
2633
2752
|
else
|
2634
2753
|
expanded_expression
|
@@ -2676,8 +2795,8 @@ module MarkdownExec
|
|
2676
2795
|
[block_name_from_cli, now_using_cli]
|
2677
2796
|
end
|
2678
2797
|
|
2679
|
-
def mdoc_and_blocks_from_nested_files
|
2680
|
-
menu_blocks = blocks_from_nested_files
|
2798
|
+
def mdoc_and_blocks_from_nested_files(source_id: nil)
|
2799
|
+
menu_blocks = blocks_from_nested_files(source_id: source_id)
|
2681
2800
|
mdoc = MDoc.new(menu_blocks) do |nopts|
|
2682
2801
|
@delegate_object.merge!(nopts)
|
2683
2802
|
end
|
@@ -2687,12 +2806,19 @@ module MarkdownExec
|
|
2687
2806
|
## Handles the file loading and returns the blocks
|
2688
2807
|
# in the file and MDoc instance
|
2689
2808
|
#
|
2690
|
-
def mdoc_menu_and_blocks_from_nested_files(link_state,
|
2809
|
+
def mdoc_menu_and_blocks_from_nested_files(link_state, source_id: '')
|
2691
2810
|
# read blocks, load document opts block, and re-process blocks
|
2692
2811
|
#
|
2693
|
-
all_blocks, mdoc = mdoc_and_blocks_from_nested_files
|
2694
|
-
if load_auto_opts_block(all_blocks,
|
2695
|
-
all_blocks, mdoc = mdoc_and_blocks_from_nested_files
|
2812
|
+
all_blocks, mdoc = mdoc_and_blocks_from_nested_files(source_id: source_id)
|
2813
|
+
if load_auto_opts_block(all_blocks, mdoc: mdoc)
|
2814
|
+
all_blocks, mdoc = mdoc_and_blocks_from_nested_files(source_id: source_id)
|
2815
|
+
end
|
2816
|
+
|
2817
|
+
# load document shell block
|
2818
|
+
#
|
2819
|
+
if code_lines = load_document_shell_block(all_blocks, mdoc: mdoc)
|
2820
|
+
next_state_set_code(nil, link_state, code_lines)
|
2821
|
+
link_state.inherited_lines = code_lines
|
2696
2822
|
end
|
2697
2823
|
|
2698
2824
|
# load document vars block
|
@@ -2700,11 +2826,7 @@ module MarkdownExec
|
|
2700
2826
|
if code_lines = load_auto_vars_block(all_blocks)
|
2701
2827
|
new_code = HashDelegator.code_merge(link_state.inherited_lines,
|
2702
2828
|
code_lines)
|
2703
|
-
next_state_set_code(
|
2704
|
-
nil,
|
2705
|
-
link_state,
|
2706
|
-
new_code
|
2707
|
-
)
|
2829
|
+
next_state_set_code(nil, link_state, new_code)
|
2708
2830
|
link_state.inherited_lines = new_code
|
2709
2831
|
end
|
2710
2832
|
|
@@ -2714,10 +2836,22 @@ module MarkdownExec
|
|
2714
2836
|
@delegate_object.merge!(compressed_ids: @compressed_ids)
|
2715
2837
|
)
|
2716
2838
|
|
2839
|
+
# re-expand blocks
|
2840
|
+
menu_blocks.each do |fcb|
|
2841
|
+
fcb.body = fcb.raw_body || fcb.body || []
|
2842
|
+
fcb.dname = fcb.raw_dname || fcb.dname
|
2843
|
+
fcb.s0printable = fcb.raw_s0printable || fcb.s0printable
|
2844
|
+
fcb.s1decorated = fcb.raw_s1decorated || fcb.s1decorated
|
2845
|
+
expand_references!(fcb, link_state)
|
2846
|
+
end
|
2847
|
+
|
2717
2848
|
# chrome for menu
|
2718
2849
|
#
|
2719
|
-
add_menu_chrome_blocks!(
|
2720
|
-
|
2850
|
+
add_menu_chrome_blocks!(
|
2851
|
+
link_state: link_state,
|
2852
|
+
menu_blocks: menu_blocks,
|
2853
|
+
source_id: source_id
|
2854
|
+
)
|
2721
2855
|
|
2722
2856
|
### compress empty lines
|
2723
2857
|
HashDelegator.delete_consecutive_blank_lines!(menu_blocks)
|
@@ -2743,6 +2877,7 @@ module MarkdownExec
|
|
2743
2877
|
dname: HashDelegator.new(@delegate_object).string_send_color(
|
2744
2878
|
document_glob, :menu_inherited_lines_color
|
2745
2879
|
),
|
2880
|
+
# 2025-01-03 menu item is disabled ∴ does not need a recall id
|
2746
2881
|
oname: formatted_name
|
2747
2882
|
)
|
2748
2883
|
|
@@ -2783,6 +2918,22 @@ module MarkdownExec
|
|
2783
2918
|
end
|
2784
2919
|
end
|
2785
2920
|
|
2921
|
+
def menu_compress_collapsible_block(selected)
|
2922
|
+
@compressed_ids.merge!(selected.id => selected.level)
|
2923
|
+
end
|
2924
|
+
|
2925
|
+
def menu_expand_collapsible_block(selected)
|
2926
|
+
@compressed_ids.delete(selected.id)
|
2927
|
+
end
|
2928
|
+
|
2929
|
+
def menu_toggle_collapsible_block(selected)
|
2930
|
+
if @compressed_ids.keys.include?(selected.id)
|
2931
|
+
menu_expand_collapsible_block(selected)
|
2932
|
+
else
|
2933
|
+
menu_compress_collapsible_block(selected)
|
2934
|
+
end
|
2935
|
+
end
|
2936
|
+
|
2786
2937
|
# If a method is missing, treat it as a key for the @delegate_object.
|
2787
2938
|
def method_missing(method_name, *args, &block)
|
2788
2939
|
if @delegate_object.respond_to?(method_name)
|
@@ -3435,7 +3586,7 @@ module MarkdownExec
|
|
3435
3586
|
formatted = formatted_expression(expression)
|
3436
3587
|
|
3437
3588
|
# Handle wildcards or direct file specification
|
3438
|
-
if
|
3589
|
+
if contains_glob?(formatted)
|
3439
3590
|
save_filespec_wildcard_expansion(formatted)
|
3440
3591
|
else
|
3441
3592
|
formatted
|
@@ -3579,11 +3730,14 @@ module MarkdownExec
|
|
3579
3730
|
item == selection
|
3580
3731
|
end
|
3581
3732
|
end
|
3733
|
+
|
3734
|
+
# new FCB if selected is not an object
|
3582
3735
|
if selected.instance_of?(String)
|
3583
3736
|
selected = FCB.new(dname: selected)
|
3584
3737
|
elsif selected.instance_of?(Hash)
|
3585
3738
|
selected = FCB.new(selected)
|
3586
3739
|
end
|
3740
|
+
|
3587
3741
|
unless selected
|
3588
3742
|
HashDelegator.error_handler('select_option_with_metadata',
|
3589
3743
|
error: 'menu item not found')
|
@@ -3651,7 +3805,9 @@ module MarkdownExec
|
|
3651
3805
|
# @param fenced_start_extended_regex [Regexp]
|
3652
3806
|
# Regular expression to identify fenced block start.
|
3653
3807
|
# @return [MarkdownExec::FCB] A new FCB instance with the parsed attributes.
|
3654
|
-
def start_fenced_block(
|
3808
|
+
def start_fenced_block(
|
3809
|
+
line, headings, fenced_start_extended_regex, source_id: nil
|
3810
|
+
)
|
3655
3811
|
fcb_title_groups = NamedCaptureExtractor.extract_named_groups(
|
3656
3812
|
line, fenced_start_extended_regex
|
3657
3813
|
)
|
@@ -3702,6 +3858,7 @@ module MarkdownExec
|
|
3702
3858
|
disabled: disabled,
|
3703
3859
|
dname: dname,
|
3704
3860
|
headings: headings,
|
3861
|
+
id: source_id.to_s,
|
3705
3862
|
indent: fcb_title_groups.fetch(:indent, ''),
|
3706
3863
|
nickname: nickname,
|
3707
3864
|
oname: oname,
|
@@ -3709,10 +3866,10 @@ module MarkdownExec
|
|
3709
3866
|
shell: fcb_title_groups.fetch(:shell, ''),
|
3710
3867
|
start_line: line,
|
3711
3868
|
stdin: if (tn = rest.match(/<(?<type>\$)?(?<name>[A-Za-z_-]\S+)/))
|
3712
|
-
NamedCaptureExtractor.
|
3869
|
+
NamedCaptureExtractor.extract_named_group_match_data(tn)
|
3713
3870
|
end,
|
3714
3871
|
stdout: if (tn = rest.match(/>(?<type>\$)?(?<name>[\w.\-]+)/))
|
3715
|
-
NamedCaptureExtractor.
|
3872
|
+
NamedCaptureExtractor.extract_named_group_match_data(tn)
|
3716
3873
|
end,
|
3717
3874
|
title: title,
|
3718
3875
|
type: fcb_title_groups.fetch(:type, ''),
|
@@ -3764,7 +3921,7 @@ module MarkdownExec
|
|
3764
3921
|
##
|
3765
3922
|
def update_line_and_block_state(
|
3766
3923
|
nested_line, state, selected_types,
|
3767
|
-
|
3924
|
+
source_id:,
|
3768
3925
|
&block
|
3769
3926
|
)
|
3770
3927
|
line = nested_line.to_s
|
@@ -3784,7 +3941,8 @@ module MarkdownExec
|
|
3784
3941
|
#
|
3785
3942
|
state[:fcb] = start_fenced_block(
|
3786
3943
|
line, state[:headings],
|
3787
|
-
@delegate_object[:fenced_start_extended_regex]
|
3944
|
+
@delegate_object[:fenced_start_extended_regex],
|
3945
|
+
source_id: source_id
|
3788
3946
|
)
|
3789
3947
|
state[:fcb][:depth] = nested_line[:depth]
|
3790
3948
|
state[:fcb][:indention] = nested_line[:indention]
|
@@ -3801,8 +3959,9 @@ module MarkdownExec
|
|
3801
3959
|
@delegate_object[:menu_include_imported_notes]
|
3802
3960
|
# add line if it is depth 0 or option allows it
|
3803
3961
|
#
|
3804
|
-
HashDelegator.yield_line_if_selected(
|
3805
|
-
|
3962
|
+
HashDelegator.yield_line_if_selected(
|
3963
|
+
line, selected_types, source_id: source_id, &block
|
3964
|
+
)
|
3806
3965
|
end
|
3807
3966
|
end
|
3808
3967
|
|
@@ -4078,15 +4237,20 @@ module MarkdownExec
|
|
4078
4237
|
end
|
4079
4238
|
end
|
4080
4239
|
|
4240
|
+
count = 0
|
4081
4241
|
InputSequencer.new(
|
4082
4242
|
@delegate_object[:filename],
|
4083
4243
|
block_list
|
4084
4244
|
).run do |msg, data|
|
4245
|
+
count += 1
|
4085
4246
|
case msg
|
4086
4247
|
when :parse_document # once for each menu
|
4087
|
-
|
4088
|
-
|
4089
|
-
|
4248
|
+
count = 0
|
4249
|
+
vux_parse_document(source_id: "#{@delegate_object[:filename]}_vmlpd")
|
4250
|
+
vux_menu_append_history_files(
|
4251
|
+
formatted_choice_ostructs,
|
4252
|
+
source_id: "#{@delegate_object[:filename]}_vmlhf"
|
4253
|
+
)
|
4090
4254
|
vux_publish_document_file_name_for_external_automation
|
4091
4255
|
|
4092
4256
|
when :display_menu
|
@@ -4097,7 +4261,7 @@ module MarkdownExec
|
|
4097
4261
|
# yield :end_of_cli, @delegate_object
|
4098
4262
|
|
4099
4263
|
if @delegate_object[:list_blocks]
|
4100
|
-
list_blocks
|
4264
|
+
list_blocks(source_id: "#{@delegate_object[:filename]}_vmleoc")
|
4101
4265
|
:exit
|
4102
4266
|
end
|
4103
4267
|
|
@@ -4132,8 +4296,9 @@ module MarkdownExec
|
|
4132
4296
|
end
|
4133
4297
|
end
|
4134
4298
|
|
4135
|
-
def vux_menu_append_history_files(
|
4136
|
-
|
4299
|
+
def vux_menu_append_history_files(
|
4300
|
+
formatted_choice_ostructs, source_id: ''
|
4301
|
+
)
|
4137
4302
|
if @delegate_object[:menu_for_history]
|
4138
4303
|
history_files(
|
4139
4304
|
@dml_link_state,
|
@@ -4145,8 +4310,8 @@ module MarkdownExec
|
|
4145
4310
|
dml_menu_append_chrome_item(
|
4146
4311
|
formatted_choice_ostructs[:history].oname, files.count,
|
4147
4312
|
'files',
|
4148
|
-
|
4149
|
-
|
4313
|
+
menu_state: MenuState::HISTORY,
|
4314
|
+
source_id: source_id
|
4150
4315
|
)
|
4151
4316
|
end
|
4152
4317
|
end
|
@@ -4168,38 +4333,38 @@ module MarkdownExec
|
|
4168
4333
|
if files.count.positive?
|
4169
4334
|
dml_menu_append_chrome_item(
|
4170
4335
|
formatted_choice_ostructs[:load].dname, files.count, 'files',
|
4171
|
-
|
4172
|
-
|
4336
|
+
menu_state: MenuState::LOAD,
|
4337
|
+
source_id: "#{source_id}_vmahf_load"
|
4173
4338
|
)
|
4174
4339
|
end
|
4175
4340
|
if @delegate_object[:menu_inherited_lines_edit_always] ||
|
4176
4341
|
lines_count.positive?
|
4177
4342
|
dml_menu_append_chrome_item(
|
4178
4343
|
formatted_choice_ostructs[:edit].dname, lines_count, 'lines',
|
4179
|
-
|
4180
|
-
|
4344
|
+
menu_state: MenuState::EDIT,
|
4345
|
+
source_id: "#{source_id}_vmahf_edit"
|
4181
4346
|
)
|
4182
4347
|
end
|
4183
4348
|
if lines_count.positive?
|
4184
4349
|
dml_menu_append_chrome_item(
|
4185
4350
|
formatted_choice_ostructs[:save].dname, 1, '',
|
4186
|
-
|
4187
|
-
|
4351
|
+
menu_state: MenuState::SAVE,
|
4352
|
+
source_id: "#{source_id}_vmahf_save"
|
4188
4353
|
)
|
4189
4354
|
end
|
4190
4355
|
if lines_count.positive?
|
4191
4356
|
dml_menu_append_chrome_item(
|
4192
4357
|
formatted_choice_ostructs[:view].dname, 1, '',
|
4193
|
-
|
4194
|
-
|
4358
|
+
menu_state: MenuState::VIEW,
|
4359
|
+
source_id: "#{source_id}_vmahf_view"
|
4195
4360
|
)
|
4196
4361
|
end
|
4197
4362
|
# rubocop:disable Style/GuardClause
|
4198
4363
|
if @delegate_object[:menu_with_shell]
|
4199
4364
|
dml_menu_append_chrome_item(
|
4200
4365
|
formatted_choice_ostructs[:shell].dname, 1, '',
|
4201
|
-
|
4202
|
-
|
4366
|
+
menu_state: MenuState::SHELL,
|
4367
|
+
source_id: "#{source_id}_vmahf_shell"
|
4203
4368
|
)
|
4204
4369
|
end
|
4205
4370
|
# rubocop:enable Style/GuardClause
|
@@ -4217,7 +4382,7 @@ module MarkdownExec
|
|
4217
4382
|
)
|
4218
4383
|
end
|
4219
4384
|
|
4220
|
-
def vux_parse_document(
|
4385
|
+
def vux_parse_document(source_id: '')
|
4221
4386
|
@run_state.batch_index += 1
|
4222
4387
|
@run_state.in_own_window = false
|
4223
4388
|
|
@@ -4239,7 +4404,9 @@ module MarkdownExec
|
|
4239
4404
|
# update @delegate_object and @menu_base_options in auto_load
|
4240
4405
|
#
|
4241
4406
|
@dml_blocks_in_file, @dml_menu_blocks, @dml_mdoc =
|
4242
|
-
mdoc_menu_and_blocks_from_nested_files(
|
4407
|
+
mdoc_menu_and_blocks_from_nested_files(
|
4408
|
+
@dml_link_state, source_id: source_id
|
4409
|
+
)
|
4243
4410
|
dump_delobj(@dml_blocks_in_file, @dml_menu_blocks, @dml_link_state)
|
4244
4411
|
end
|
4245
4412
|
|