markdown_exec 2.0.6 → 2.0.8
Sign up to get free protection for your applications and to get access to all the features.
- 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
|