markdown_exec 2.0.6 → 2.0.8
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 +4 -4
- data/.rubocop.yml +10 -2
- data/CHANGELOG.md +40 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -0
- data/bin/tab_completion.sh +2 -2
- data/examples/interrupt.md +9 -0
- data/examples/line-wrapping.md +17 -0
- data/examples/nickname.md +46 -9
- data/examples/pause-after-execution.md +9 -0
- data/lib/colorize.rb +25 -0
- data/lib/constants.rb +1 -0
- data/lib/fcb.rb +15 -0
- data/lib/hash_delegator.rb +390 -100
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +1 -0
- data/lib/mdoc.rb +9 -14
- data/lib/menu.src.yml +45 -13
- data/lib/menu.yml +32 -14
- data/lib/resize_terminal.rb +215 -0
- data/lib/saved_assets.rb +4 -3
- metadata +6 -2
data/lib/markdown_exec.rb
CHANGED
@@ -749,6 +749,7 @@ module MarkdownExec
|
|
749
749
|
def select_option_or_exit(prompt_text, strings, opts = {})
|
750
750
|
result = @options.select_option_with_metadata(prompt_text, strings,
|
751
751
|
opts)
|
752
|
+
### 2024-04-20 what for?
|
752
753
|
# return unless result.fetch(:option, nil)
|
753
754
|
|
754
755
|
result[:selected]
|
data/lib/mdoc.rb
CHANGED
@@ -72,11 +72,10 @@ module MarkdownExec
|
|
72
72
|
#
|
73
73
|
def collect_block_dependencies(anyname:)
|
74
74
|
name_block = get_block_by_anyname(anyname)
|
75
|
-
if name_block.nil? || name_block.keys.empty?
|
76
|
-
|
77
|
-
|
75
|
+
raise "Named code block `#{anyname}` not found. (@#{__LINE__})" if name_block.nil? || name_block.keys.empty?
|
76
|
+
|
77
|
+
nickname = name_block.pub_name
|
78
78
|
|
79
|
-
nickname = name_block[:nickname] || name_block[:oname]
|
80
79
|
dependencies = collect_dependencies(nickname)
|
81
80
|
# &bc 'dependencies.count:',dependencies.count
|
82
81
|
all_dependency_names = collect_unique_names(dependencies).push(nickname).uniq
|
@@ -85,9 +84,7 @@ module MarkdownExec
|
|
85
84
|
# select non-chrome blocks in order of appearance in source documents
|
86
85
|
#
|
87
86
|
blocks = @table.select do |fcb|
|
88
|
-
!fcb.fetch(:chrome,
|
89
|
-
false) && all_dependency_names.include?(fcb.fetch(:nickname,
|
90
|
-
nil) || fcb.fetch(:oname))
|
87
|
+
!fcb.fetch(:chrome, false) && all_dependency_names.include?(fcb.pub_name)
|
91
88
|
end
|
92
89
|
# &bc 'blocks.count:',blocks.count
|
93
90
|
|
@@ -95,7 +92,7 @@ module MarkdownExec
|
|
95
92
|
#
|
96
93
|
unmet_dependencies = all_dependency_names.dup
|
97
94
|
blocks = blocks.map do |fcb|
|
98
|
-
unmet_dependencies.delete(fcb
|
95
|
+
unmet_dependencies.delete(fcb.pub_name) # may not exist if block name is duplicated
|
99
96
|
if (call = fcb[:call])
|
100
97
|
[get_block_by_anyname("[#{call.match(/^%\((\S+) |\)/)[1]}]")
|
101
98
|
.merge({ cann: call })]
|
@@ -124,7 +121,7 @@ module MarkdownExec
|
|
124
121
|
# &bc 'blocks.count:',blocks.count
|
125
122
|
|
126
123
|
block_search.merge(
|
127
|
-
{ block_names: blocks.map
|
124
|
+
{ block_names: blocks.map(&:pub_name),
|
128
125
|
code: blocks.map do |fcb|
|
129
126
|
if fcb[:cann]
|
130
127
|
collect_block_code_cann(fcb)
|
@@ -136,7 +133,7 @@ module MarkdownExec
|
|
136
133
|
elsif fcb[:shell] == BlockType::PORT
|
137
134
|
collect_block_code_shell(fcb)
|
138
135
|
elsif label_body
|
139
|
-
block_name_for_bash_comment =
|
136
|
+
block_name_for_bash_comment = fcb.pub_name.gsub(/\s+/, '_')
|
140
137
|
[label_format_above && format(label_format_above,
|
141
138
|
block_source.merge({ block_name: block_name_for_bash_comment }))] +
|
142
139
|
fcb[:body] +
|
@@ -198,7 +195,7 @@ module MarkdownExec
|
|
198
195
|
|
199
196
|
### hide rows correctly
|
200
197
|
|
201
|
-
|
198
|
+
unless options[:menu_include_imported_blocks]
|
202
199
|
selrows = selrows.reject do |block|
|
203
200
|
block.fetch(:depth, 0).positive?
|
204
201
|
end
|
@@ -287,9 +284,7 @@ module MarkdownExec
|
|
287
284
|
return memo if memo.keys.include? source
|
288
285
|
|
289
286
|
block = get_block_by_anyname(source)
|
290
|
-
if block.nil? || block.keys.empty?
|
291
|
-
raise "Named code block `#{source}` not found. (@#{__LINE__})"
|
292
|
-
end
|
287
|
+
raise "Named code block `#{source}` not found. (@#{__LINE__})" if block.nil? || block.keys.empty?
|
293
288
|
|
294
289
|
memo[source] = block[:reqs]
|
295
290
|
return memo unless memo[source]&.count&.positive?
|
data/lib/menu.src.yml
CHANGED
@@ -106,6 +106,12 @@
|
|
106
106
|
:opt_name: display_level_xbase_prefix
|
107
107
|
:procname: val_as_str
|
108
108
|
|
109
|
+
# - :default: "(document_link)"
|
110
|
+
# :description: Name of Link block to load with the document
|
111
|
+
# :env_var: MDE_DOCUMENT_LOAD_LINK_BLOCK_NAME
|
112
|
+
# :opt_name: document_load_link_block_name
|
113
|
+
# :procname: val_as_str
|
114
|
+
|
109
115
|
- :default: "(document_options)"
|
110
116
|
:description: Name of Opts block to load with the document
|
111
117
|
:env_var: MDE_DOCUMENT_LOAD_OPTS_BLOCK_NAME
|
@@ -227,6 +233,8 @@
|
|
227
233
|
:opt_name: exclude_expect_blocks
|
228
234
|
:procname: val_as_bool
|
229
235
|
|
236
|
+
# - :default: >
|
237
|
+
# osascript scripts/applescript/mde.applescript "%{batch_index}" "%{home}" " %{started_at} - %{document_filename} - %{block_name} " "%{script_filespec}" "%{output_filespec}"
|
230
238
|
- :default: >
|
231
239
|
osascript -e '
|
232
240
|
on run argv
|
@@ -328,17 +336,17 @@
|
|
328
336
|
:opt_name: find_path
|
329
337
|
:procname: val_as_str
|
330
338
|
|
331
|
-
- :default: "^# *(?<
|
339
|
+
- :default: "^#(?<line>(?!#)(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
332
340
|
:env_var: MDE_HEADING1_MATCH
|
333
341
|
:opt_name: heading1_match
|
334
342
|
:procname: val_as_str
|
335
343
|
|
336
|
-
- :default: "^## *(?<
|
344
|
+
- :default: "^##(?<line>(?!#)(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
337
345
|
:env_var: MDE_HEADING2_MATCH
|
338
346
|
:opt_name: heading2_match
|
339
347
|
:procname: val_as_str
|
340
348
|
|
341
|
-
- :default: "^### *(?<
|
349
|
+
- :default: "^###(?<line>(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
342
350
|
:env_var: MDE_HEADING3_MATCH
|
343
351
|
:opt_name: heading3_match
|
344
352
|
:procname: val_as_str
|
@@ -496,7 +504,7 @@
|
|
496
504
|
:opt_name: menu_divider_format
|
497
505
|
:procname: val_as_str
|
498
506
|
|
499
|
-
- :default: "^:::
|
507
|
+
- :default: "^:::(?<line>(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
500
508
|
:description: Pattern for topics/dividers in block selection menu
|
501
509
|
:env_var: MDE_MENU_DIVIDER_MATCH
|
502
510
|
:opt_name: menu_divider_match
|
@@ -529,37 +537,40 @@
|
|
529
537
|
:opt_name: menu_final_divider
|
530
538
|
:procname: val_as_str
|
531
539
|
|
532
|
-
- :default:
|
540
|
+
- :default: fg_bg_rgbh_80_80_c0_10_10_20
|
533
541
|
:description: Color for heading 1 in menu
|
534
542
|
:env_var: MDE_MENU_HEADING1_COLOR
|
535
543
|
:opt_name: menu_heading1_color
|
536
544
|
:procname: val_as_str
|
537
545
|
|
538
|
-
|
546
|
+
# strip heading tag
|
547
|
+
- :default: "%{line}"
|
539
548
|
:description: format for menu heading1 in menu
|
540
549
|
:env_var: MDE_MENU_HEADING1_FORMAT
|
541
550
|
:opt_name: menu_heading1_format
|
542
551
|
:procname: val_as_str
|
543
552
|
|
544
|
-
- :default:
|
553
|
+
- :default: fg_bg_rgbh_60_60_c0_10_10_20
|
545
554
|
:description: Color for heading 2 in menu
|
546
555
|
:env_var: MDE_MENU_HEADING2_COLOR
|
547
556
|
:opt_name: menu_heading2_color
|
548
557
|
:procname: val_as_str
|
549
558
|
|
550
|
-
|
559
|
+
# strip heading tag
|
560
|
+
- :default: "%{line}"
|
551
561
|
:description: format for menu heading2 in menu
|
552
562
|
:env_var: MDE_MENU_HEADING2_FORMAT
|
553
563
|
:opt_name: menu_heading2_format
|
554
564
|
:procname: val_as_str
|
555
565
|
|
556
|
-
- :default:
|
566
|
+
- :default: fg_bg_rgbh_40_40_c0_10_10_20
|
557
567
|
:description: Color for heading 3 in menu
|
558
568
|
:env_var: MDE_MENU_HEADING3_COLOR
|
559
569
|
:opt_name: menu_heading3_color
|
560
570
|
:procname: val_as_str
|
561
571
|
|
562
|
-
|
572
|
+
# strip heading tag
|
573
|
+
- :default: "%{line}"
|
563
574
|
:description: format for menu heading3 in menu
|
564
575
|
:env_var: MDE_MENU_HEADING3_FORMAT
|
565
576
|
:opt_name: menu_heading3_format
|
@@ -624,7 +635,7 @@
|
|
624
635
|
:opt_name: menu_link_format
|
625
636
|
:procname: val_as_str
|
626
637
|
|
627
|
-
- :default:
|
638
|
+
- :default: fg_rgbh_c0_c0_c0
|
628
639
|
:description: Color of menu note
|
629
640
|
:env_var: MDE_MENU_NOTE_COLOR
|
630
641
|
:opt_name: menu_note_color
|
@@ -637,7 +648,7 @@
|
|
637
648
|
:procname: val_as_str
|
638
649
|
|
639
650
|
## all lines that do not start with "/ " are notes
|
640
|
-
- :default: "^(?<line>(?!/ )
|
651
|
+
- :default: "^(?<line>(?!/ )(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
641
652
|
:description: Pattern for notes in block selection menu
|
642
653
|
:env_var: MDE_MENU_NOTE_MATCH
|
643
654
|
:opt_name: menu_note_match
|
@@ -678,6 +689,13 @@
|
|
678
689
|
:opt_name: menu_option_save_name
|
679
690
|
:procname: val_as_str
|
680
691
|
|
692
|
+
- :default:
|
693
|
+
:line: "! Shell"
|
694
|
+
:description: Text for Shell option
|
695
|
+
:env_var: MDE_MENU_OPTION_SHELL_NAME
|
696
|
+
:opt_name: menu_option_shell_name
|
697
|
+
:procname: val_as_str
|
698
|
+
|
681
699
|
- :default:
|
682
700
|
:line: "* View"
|
683
701
|
:description: Text for View option
|
@@ -709,6 +727,13 @@
|
|
709
727
|
:opt_name: menu_persist_block_name
|
710
728
|
:procname: val_as_str
|
711
729
|
|
730
|
+
- :arg_name: BOOL
|
731
|
+
:default: true
|
732
|
+
:description: Resize terminal when displaying menu.
|
733
|
+
:env_var: MDE_MENU_RESIZE_TERMINAL
|
734
|
+
:opt_name: menu_resize_terminal
|
735
|
+
:procname: val_as_bool
|
736
|
+
|
712
737
|
- :default: fg_rgbh_ff_ff_ff
|
713
738
|
:description: Color of menu task
|
714
739
|
:env_var: MDE_MENU_TASK_COLOR
|
@@ -772,6 +797,13 @@
|
|
772
797
|
:opt_name: menu_with_inherited_lines
|
773
798
|
:procname: val_as_bool
|
774
799
|
|
800
|
+
- :arg_name: BOOL
|
801
|
+
:default: true
|
802
|
+
:description: Display Shell option in menu
|
803
|
+
:env_var: MDE_MENU_WITH_SHELL
|
804
|
+
:opt_name: menu_with_shell
|
805
|
+
:procname: val_as_bool
|
806
|
+
|
775
807
|
- :arg_name: BOOL
|
776
808
|
:default: false
|
777
809
|
:description: Hide decorative menu entries
|
@@ -874,7 +906,7 @@
|
|
874
906
|
|
875
907
|
- :arg_name: BOOL
|
876
908
|
:default: false
|
877
|
-
:description:
|
909
|
+
:description: Whether to pause after manually executing a block and the next menu
|
878
910
|
:env_var: MDE_PAUSE_AFTER_SCRIPT_EXECUTION
|
879
911
|
:opt_name: pause_after_script_execution
|
880
912
|
:procname: val_as_bool
|
data/lib/menu.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# MDE - Markdown Executor (2.0.
|
1
|
+
# MDE - Markdown Executor (2.0.8)
|
2
2
|
---
|
3
3
|
- :description: Show current configuration values
|
4
4
|
:procname: show_config
|
@@ -285,15 +285,15 @@
|
|
285
285
|
:long_name: find-path
|
286
286
|
:opt_name: find_path
|
287
287
|
:procname: val_as_str
|
288
|
-
- :default: "^# *(?<
|
288
|
+
- :default: "^#(?<line>(?!#)(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
289
289
|
:env_var: MDE_HEADING1_MATCH
|
290
290
|
:opt_name: heading1_match
|
291
291
|
:procname: val_as_str
|
292
|
-
- :default: "^## *(?<
|
292
|
+
- :default: "^##(?<line>(?!#)(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
293
293
|
:env_var: MDE_HEADING2_MATCH
|
294
294
|
:opt_name: heading2_match
|
295
295
|
:procname: val_as_str
|
296
|
-
- :default: "^### *(?<
|
296
|
+
- :default: "^###(?<line>(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
297
297
|
:env_var: MDE_HEADING3_MATCH
|
298
298
|
:opt_name: heading3_match
|
299
299
|
:procname: val_as_str
|
@@ -425,7 +425,7 @@
|
|
425
425
|
:env_var: MDE_MENU_DIVIDER_FORMAT
|
426
426
|
:opt_name: menu_divider_format
|
427
427
|
:procname: val_as_str
|
428
|
-
- :default: "^:::
|
428
|
+
- :default: "^:::(?<line>(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
429
429
|
:description: Pattern for topics/dividers in block selection menu
|
430
430
|
:env_var: MDE_MENU_DIVIDER_MATCH
|
431
431
|
:opt_name: menu_divider_match
|
@@ -453,32 +453,32 @@
|
|
453
453
|
:env_var: MDE_MENU_FINAL_DIVIDER
|
454
454
|
:opt_name: menu_final_divider
|
455
455
|
:procname: val_as_str
|
456
|
-
- :default:
|
456
|
+
- :default: fg_bg_rgbh_80_80_c0_10_10_20
|
457
457
|
:description: Color for heading 1 in menu
|
458
458
|
:env_var: MDE_MENU_HEADING1_COLOR
|
459
459
|
:opt_name: menu_heading1_color
|
460
460
|
:procname: val_as_str
|
461
|
-
- :default: "
|
461
|
+
- :default: "%{line}"
|
462
462
|
:description: format for menu heading1 in menu
|
463
463
|
:env_var: MDE_MENU_HEADING1_FORMAT
|
464
464
|
:opt_name: menu_heading1_format
|
465
465
|
:procname: val_as_str
|
466
|
-
- :default:
|
466
|
+
- :default: fg_bg_rgbh_60_60_c0_10_10_20
|
467
467
|
:description: Color for heading 2 in menu
|
468
468
|
:env_var: MDE_MENU_HEADING2_COLOR
|
469
469
|
:opt_name: menu_heading2_color
|
470
470
|
:procname: val_as_str
|
471
|
-
- :default: "
|
471
|
+
- :default: "%{line}"
|
472
472
|
:description: format for menu heading2 in menu
|
473
473
|
:env_var: MDE_MENU_HEADING2_FORMAT
|
474
474
|
:opt_name: menu_heading2_format
|
475
475
|
:procname: val_as_str
|
476
|
-
- :default:
|
476
|
+
- :default: fg_bg_rgbh_40_40_c0_10_10_20
|
477
477
|
:description: Color for heading 3 in menu
|
478
478
|
:env_var: MDE_MENU_HEADING3_COLOR
|
479
479
|
:opt_name: menu_heading3_color
|
480
480
|
:procname: val_as_str
|
481
|
-
- :default: "
|
481
|
+
- :default: "%{line}"
|
482
482
|
:description: format for menu heading3 in menu
|
483
483
|
:env_var: MDE_MENU_HEADING3_FORMAT
|
484
484
|
:opt_name: menu_heading3_format
|
@@ -532,7 +532,7 @@
|
|
532
532
|
:env_var: MDE_MENU_LINK_FORMAT
|
533
533
|
:opt_name: menu_link_format
|
534
534
|
:procname: val_as_str
|
535
|
-
- :default:
|
535
|
+
- :default: fg_rgbh_c0_c0_c0
|
536
536
|
:description: Color of menu note
|
537
537
|
:env_var: MDE_MENU_NOTE_COLOR
|
538
538
|
:opt_name: menu_note_color
|
@@ -542,7 +542,7 @@
|
|
542
542
|
:env_var: MDE_MENU_NOTE_FORMAT
|
543
543
|
:opt_name: menu_note_format
|
544
544
|
:procname: val_as_str
|
545
|
-
- :default: "^(?<line>(?!/ )
|
545
|
+
- :default: "^(?<line>(?!/ )(?<indent>[ \t]*)(?<text>.*?)(?<trailing>[ \t]*))?$"
|
546
546
|
:description: Pattern for notes in block selection menu
|
547
547
|
:env_var: MDE_MENU_NOTE_MATCH
|
548
548
|
:opt_name: menu_note_match
|
@@ -577,6 +577,12 @@
|
|
577
577
|
:env_var: MDE_MENU_OPTION_SAVE_NAME
|
578
578
|
:opt_name: menu_option_save_name
|
579
579
|
:procname: val_as_str
|
580
|
+
- :default:
|
581
|
+
:line: "! Shell"
|
582
|
+
:description: Text for Shell option
|
583
|
+
:env_var: MDE_MENU_OPTION_SHELL_NAME
|
584
|
+
:opt_name: menu_option_shell_name
|
585
|
+
:procname: val_as_str
|
580
586
|
- :default:
|
581
587
|
:line: "* View"
|
582
588
|
:description: Text for View option
|
@@ -603,6 +609,12 @@
|
|
603
609
|
:env_var: MDE_MENU_PERSIST_BLOCK_NAME
|
604
610
|
:opt_name: menu_persist_block_name
|
605
611
|
:procname: val_as_str
|
612
|
+
- :arg_name: BOOL
|
613
|
+
:default: true
|
614
|
+
:description: Resize terminal when displaying menu.
|
615
|
+
:env_var: MDE_MENU_RESIZE_TERMINAL
|
616
|
+
:opt_name: menu_resize_terminal
|
617
|
+
:procname: val_as_bool
|
606
618
|
- :default: fg_rgbh_ff_ff_ff
|
607
619
|
:description: Color of menu task
|
608
620
|
:env_var: MDE_MENU_TASK_COLOR
|
@@ -656,6 +668,12 @@
|
|
656
668
|
:env_var: MDE_MENU_WITH_INHERITED_LINES
|
657
669
|
:opt_name: menu_with_inherited_lines
|
658
670
|
:procname: val_as_bool
|
671
|
+
- :arg_name: BOOL
|
672
|
+
:default: true
|
673
|
+
:description: Display Shell option in menu
|
674
|
+
:env_var: MDE_MENU_WITH_SHELL
|
675
|
+
:opt_name: menu_with_shell
|
676
|
+
:procname: val_as_bool
|
659
677
|
- :arg_name: BOOL
|
660
678
|
:default: false
|
661
679
|
:description: Hide decorative menu entries
|
@@ -743,7 +761,7 @@
|
|
743
761
|
:short_name: p
|
744
762
|
- :arg_name: BOOL
|
745
763
|
:default: false
|
746
|
-
:description:
|
764
|
+
:description: Whether to pause after manually executing a block and the next menu
|
747
765
|
:env_var: MDE_PAUSE_AFTER_SCRIPT_EXECUTION
|
748
766
|
:opt_name: pause_after_script_execution
|
749
767
|
:procname: val_as_bool
|
@@ -0,0 +1,215 @@
|
|
1
|
+
#!/usr/bin/env bundle exec ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
require 'io/console'
|
6
|
+
require 'timeout'
|
7
|
+
|
8
|
+
# This function attempts to resize the terminal to its maximum supported size.
|
9
|
+
# It checks if the script is running in an interactive terminal with no arguments.
|
10
|
+
# If so, it sends escape sequences to query the terminal size and reads the response.
|
11
|
+
# It then compares the current terminal size with the calculated size and adjusts if necessary.
|
12
|
+
# If the terminal emulator is unsupported, it prints an error message.
|
13
|
+
def resize_terminal(show_dims: false, show_rectangle: false)
|
14
|
+
# Check if running in an interactive terminal and no arguments are provided
|
15
|
+
if $stdin.tty? && ARGV.empty?
|
16
|
+
begin
|
17
|
+
# Save the current state and send the escape sequence to get the cursor position
|
18
|
+
print "\e7\e[r\e[999;999H\e[6n\e8"
|
19
|
+
$stdout.flush
|
20
|
+
|
21
|
+
# Read the response from the terminal
|
22
|
+
response = String.new
|
23
|
+
Timeout.timeout(5) do
|
24
|
+
loop do
|
25
|
+
char = $stdin.getch
|
26
|
+
response << char
|
27
|
+
break if response.include?('R')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if response.empty?
|
32
|
+
warn "Error: No response received from terminal. Response: #{response.inspect}"
|
33
|
+
return 1
|
34
|
+
end
|
35
|
+
|
36
|
+
# Match the response to extract the terminal dimensions
|
37
|
+
match_data = response.match(/\[(\d+);(\d+)R/)
|
38
|
+
unless match_data
|
39
|
+
warn "Error: Failed to match terminal response pattern. Response: #{response.inspect}"
|
40
|
+
return 1
|
41
|
+
end
|
42
|
+
|
43
|
+
calculated_rows, calculated_columns = match_data.captures.map(&:to_i)
|
44
|
+
|
45
|
+
if ENV['COLUMNS'].to_i == calculated_columns && ENV['LINES'].to_i == calculated_rows
|
46
|
+
puts "#{ENV.fetch('TERM', nil)} #{calculated_columns}x#{calculated_rows}"
|
47
|
+
elsif calculated_columns.positive? && calculated_rows.positive?
|
48
|
+
warn "#{ENV.fetch('COLUMNS', nil)}x#{ENV.fetch('LINES', nil)} -> #{calculated_columns}x#{calculated_rows}" if show_dims
|
49
|
+
system("stty cols #{calculated_columns} rows #{calculated_rows}")
|
50
|
+
else
|
51
|
+
warn "Error: Calculated terminal size is invalid. Columns: #{calculated_columns}, Rows: #{calculated_rows}"
|
52
|
+
return 1
|
53
|
+
end
|
54
|
+
|
55
|
+
# Display a text rectangle if the option is enabled
|
56
|
+
display_terminal_rectangle(calculated_columns, calculated_rows) if show_rectangle
|
57
|
+
rescue Timeout::Error
|
58
|
+
warn 'Error: Timeout while reading terminal response. Unsupported terminal emulator.'
|
59
|
+
1
|
60
|
+
rescue StandardError => err
|
61
|
+
warn "Error: #{err.message}. Unsupported terminal emulator."
|
62
|
+
1
|
63
|
+
end
|
64
|
+
else
|
65
|
+
warn 'Usage: resize_terminal'
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# This function draws a rectangle of the given width and height
|
70
|
+
# with stars on the edges and empty space inside.
|
71
|
+
def display_terminal_rectangle(width, height)
|
72
|
+
puts '*' * width
|
73
|
+
(height - 2).times { puts "*#{' ' * (width - 2)}*" }
|
74
|
+
puts '*' * width
|
75
|
+
end
|
76
|
+
|
77
|
+
# resize_terminal(show_rectangle: true) if __FILE__ == $PROGRAM_NAME
|
78
|
+
return if __FILE__ != $PROGRAM_NAME
|
79
|
+
|
80
|
+
require 'minitest/autorun'
|
81
|
+
|
82
|
+
class ResizeTerminalTest < Minitest::Test
|
83
|
+
def setup
|
84
|
+
# Backup original ARGV and environment variables
|
85
|
+
@original_argv = ARGV.dup
|
86
|
+
@original_columns = ENV.fetch('COLUMNS', nil)
|
87
|
+
@original_lines = ENV.fetch('LINES', nil)
|
88
|
+
end
|
89
|
+
|
90
|
+
def teardown
|
91
|
+
# Restore original ARGV and environment variables
|
92
|
+
ARGV.replace(@original_argv)
|
93
|
+
ENV['COLUMNS'] = @original_columns
|
94
|
+
ENV['LINES'] = @original_lines
|
95
|
+
end
|
96
|
+
|
97
|
+
# def test_resize_terminal_successful
|
98
|
+
# # Simulate interactive terminal
|
99
|
+
# $stdin.stub(:tty?, true) do
|
100
|
+
# ARGV.replace([])
|
101
|
+
# ENV['COLUMNS'] = '80'
|
102
|
+
# ENV['LINES'] = '24'
|
103
|
+
# response = "\e[999;999H\e[6n\e[24;80R"
|
104
|
+
# $stdin.stub(:getch, -> { response.slice!(0) || '' }) do
|
105
|
+
# assert_output(nil, /24x80/) do
|
106
|
+
# resize_terminal
|
107
|
+
# end
|
108
|
+
# end
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
def test_resize_terminal_successful
|
112
|
+
# Simulate interactive terminal
|
113
|
+
$stdin.stub(:tty?, true) do
|
114
|
+
ARGV.replace([])
|
115
|
+
columns = 40 + (2 * rand(10))
|
116
|
+
ENV['COLUMNS'] = columns.to_s
|
117
|
+
ENV['LINES'] = '24'
|
118
|
+
response = "\e[999;999H\e[6n\e[24;#{columns}R".dup
|
119
|
+
$stdin.stub(:getch, -> { response.slice!(0) || '' }) do
|
120
|
+
assert_output("\e7\e[r\e[999;999H\e[6n\e8xterm-256color #{columns}x24\n") do
|
121
|
+
# assert_output('', '') do
|
122
|
+
resize_terminal
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
def test_resize_terminal_no_response
|
129
|
+
# Simulate interactive terminal with no response
|
130
|
+
$stdin.stub(:tty?, true) do
|
131
|
+
ARGV.replace([])
|
132
|
+
$stdin.stub(:getch, -> { '' }) do
|
133
|
+
# assert_output(nil, /Error: No response received from terminal/) do
|
134
|
+
assert_output(nil, "Error: Timeout while reading terminal response. Unsupported terminal emulator.\n") do
|
135
|
+
assert_equal 1, resize_terminal
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
def test_resize_terminal_invalid_response
|
142
|
+
# Simulate interactive terminal with invalid response
|
143
|
+
$stdin.stub(:tty?, true) do
|
144
|
+
ARGV.replace([])
|
145
|
+
response = "\e[999;999H\e[6n\e[InvalidResponse".dup
|
146
|
+
$stdin.stub(:getch, -> { response.slice!(0) || '' }) do
|
147
|
+
assert_output(nil, /Error: Failed to match terminal response pattern/) do
|
148
|
+
assert_equal 1, resize_terminal
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_resize_terminal_timeout
|
155
|
+
# Simulate interactive terminal with timeout
|
156
|
+
$stdin.stub(:tty?, true) do
|
157
|
+
ARGV.replace([])
|
158
|
+
Timeout.stub(:timeout, ->(_) { raise Timeout::Error }) do
|
159
|
+
assert_output(nil, /Error: Timeout while reading terminal response/) do
|
160
|
+
assert_equal 1, resize_terminal
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def test_resize_terminal_non_interactive
|
167
|
+
# Simulate non-interactive terminal
|
168
|
+
$stdin.stub(:tty?, false) do
|
169
|
+
assert_output(nil, /Usage: resize_terminal/) do
|
170
|
+
resize_terminal
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
# def test_resize_terminal_display_rectangle
|
176
|
+
# # Simulate interactive terminal with rectangle display
|
177
|
+
# $stdin.stub(:tty?, true) do
|
178
|
+
# ARGV.replace([])
|
179
|
+
# ENV['COLUMNS'] = '80'
|
180
|
+
# ENV['LINES'] = '24'
|
181
|
+
# response = "\e[999;999H\e[6n\e[24;80R".dup
|
182
|
+
# $stdin.stub(:getch, -> { response.slice!(0) || '' }) do
|
183
|
+
# expected_output = "\e7\e[r\e[999;999H\e[6n\e8"
|
184
|
+
# # expected_output = <<-RECTANGLE
|
185
|
+
# # ********************************************************************************
|
186
|
+
# # * *
|
187
|
+
# # * *
|
188
|
+
# # * *
|
189
|
+
# # * *
|
190
|
+
# # * *
|
191
|
+
# # * *
|
192
|
+
# # * *
|
193
|
+
# # * *
|
194
|
+
# # * *
|
195
|
+
# # * *
|
196
|
+
# # * *
|
197
|
+
# # * *
|
198
|
+
# # * *
|
199
|
+
# # * *
|
200
|
+
# # * *
|
201
|
+
# # * *
|
202
|
+
# # * *
|
203
|
+
# # * *
|
204
|
+
# # * *
|
205
|
+
# # * *
|
206
|
+
# # * *
|
207
|
+
# # ********************************************************************************
|
208
|
+
# # RECTANGLE
|
209
|
+
# assert_output(expected_output.strip) do
|
210
|
+
# resize_terminal(show_rectangle: true)
|
211
|
+
# end
|
212
|
+
# end
|
213
|
+
# end
|
214
|
+
# end
|
215
|
+
end
|
data/lib/saved_assets.rb
CHANGED
@@ -12,7 +12,8 @@ module MarkdownExec
|
|
12
12
|
# method derives a name for stdout redirection.
|
13
13
|
#
|
14
14
|
class SavedAsset
|
15
|
-
FNR11 = %r{
|
15
|
+
FNR11 = %r{[^!#%&()\+,\-0-9=A-Z_a-z~]}.freeze
|
16
|
+
# / !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
|
16
17
|
FNR12 = '_'
|
17
18
|
DEFAULT_FTIME = '%F-%H-%M-%S'
|
18
19
|
|
@@ -43,7 +44,7 @@ class SavedAssetTest < Minitest::Test
|
|
43
44
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
44
45
|
blockname = 'block/1:2'
|
45
46
|
|
46
|
-
expected_name = 'test_2023-01-01-12-00-
|
47
|
+
expected_name = 'test_2023-01-01-12-00-00_sample_txt_,_block_1_2.sh'
|
47
48
|
assert_equal expected_name, MarkdownExec::SavedAsset.script_name(
|
48
49
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
49
50
|
)
|
@@ -55,7 +56,7 @@ class SavedAssetTest < Minitest::Test
|
|
55
56
|
time = Time.new(2023, 1, 1, 12, 0, 0)
|
56
57
|
blockname = 'block/1:2'
|
57
58
|
|
58
|
-
expected_name = 'test_2023-01-01-12-00-
|
59
|
+
expected_name = 'test_2023-01-01-12-00-00_sample_txt_,_block_1_2.out.txt'
|
59
60
|
assert_equal expected_name, MarkdownExec::SavedAsset.stdout_name(
|
60
61
|
filename: filename, prefix: prefix, time: time, blockname: blockname
|
61
62
|
)
|
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.0.
|
4
|
+
version: 2.0.8
|
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-
|
11
|
+
date: 2024-06-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|
@@ -122,6 +122,8 @@ files:
|
|
122
122
|
- examples/include.md
|
123
123
|
- examples/indent.md
|
124
124
|
- examples/index.md
|
125
|
+
- examples/interrupt.md
|
126
|
+
- examples/line-wrapping.md
|
125
127
|
- examples/linked.md
|
126
128
|
- examples/linked1.md
|
127
129
|
- examples/linked2.md
|
@@ -134,6 +136,7 @@ files:
|
|
134
136
|
- examples/nickname.md
|
135
137
|
- examples/opts.md
|
136
138
|
- examples/pass-through.md
|
139
|
+
- examples/pause-after-execution.md
|
137
140
|
- examples/plant.md
|
138
141
|
- examples/port.md
|
139
142
|
- examples/search.md
|
@@ -170,6 +173,7 @@ files:
|
|
170
173
|
- lib/object_present.rb
|
171
174
|
- lib/option_value.rb
|
172
175
|
- lib/regexp.rb
|
176
|
+
- lib/resize_terminal.rb
|
173
177
|
- lib/rspec_helpers.rb
|
174
178
|
- lib/saved_assets.rb
|
175
179
|
- lib/saved_files_matcher.rb
|