markdown_exec 2.8.3 → 2.8.5

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.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +41 -0
  3. data/Gemfile.lock +1 -1
  4. data/Rakefile +33 -23
  5. data/bats/{block-types.bats → block-type-bash.bats} +0 -25
  6. data/bats/block-type-link.bats +9 -0
  7. data/bats/block-type-port.bats +16 -0
  8. data/bats/block-type-ux-allowed.bats +29 -0
  9. data/bats/block-type-ux-auto.bats +1 -1
  10. data/bats/block-type-ux-chained.bats +9 -0
  11. data/bats/block-type-ux-default.bats +8 -0
  12. data/bats/block-type-ux-echo-hash.bats +14 -0
  13. data/bats/block-type-ux-echo.bats +2 -2
  14. data/bats/block-type-ux-exec.bats +1 -1
  15. data/bats/block-type-ux-hidden.bats +9 -0
  16. data/bats/block-type-ux-invalid.bats +8 -0
  17. data/bats/block-type-ux-transform.bats +1 -1
  18. data/bats/indented-block-type-vars.bats +9 -0
  19. data/bats/line-decor-dynamic.bats +1 -1
  20. data/bats/test_helper.bash +9 -2
  21. data/bats/variable-expansion-multiline.bats +8 -0
  22. data/bats/variable-expansion.bats +1 -1
  23. data/docs/dev/block-type-ux-allowed.md +82 -0
  24. data/docs/dev/block-type-ux-auto.md +2 -1
  25. data/docs/dev/block-type-ux-chained.md +21 -0
  26. data/docs/dev/block-type-ux-default.md +42 -0
  27. data/docs/dev/block-type-ux-echo-hash.md +78 -0
  28. data/docs/dev/block-type-ux-echo.md +3 -1
  29. data/docs/dev/block-type-ux-exec.md +1 -0
  30. data/docs/dev/block-type-ux-hidden.md +21 -0
  31. data/docs/dev/block-type-ux-invalid.md +5 -0
  32. data/docs/dev/block-type-ux-require.md +9 -18
  33. data/docs/dev/indented-block-type-vars.md +6 -0
  34. data/docs/dev/line-decor-dynamic.md +2 -1
  35. data/docs/dev/variable-expansion-multiline.md +31 -0
  36. data/lib/ansi_formatter.rb +0 -1
  37. data/lib/ansi_string.rb +1 -1
  38. data/lib/array.rb +0 -1
  39. data/lib/array_util.rb +0 -1
  40. data/lib/block_label.rb +1 -1
  41. data/lib/cached_nested_file_reader.rb +1 -1
  42. data/lib/constants.rb +18 -0
  43. data/lib/directory_searcher.rb +1 -1
  44. data/lib/exceptions.rb +0 -1
  45. data/lib/fcb.rb +52 -9
  46. data/lib/filter.rb +1 -2
  47. data/lib/format_table.rb +1 -0
  48. data/lib/fout.rb +1 -1
  49. data/lib/hash.rb +0 -1
  50. data/lib/hash_delegator.rb +404 -224
  51. data/lib/link_history.rb +17 -17
  52. data/lib/logged_struct.rb +429 -0
  53. data/lib/markdown_exec/version.rb +1 -1
  54. data/lib/markdown_exec.rb +3 -3
  55. data/lib/mdoc.rb +21 -31
  56. data/lib/menu.src.yml +15 -7
  57. data/lib/menu.yml +11 -6
  58. data/lib/namer.rb +3 -6
  59. data/lib/null_result.rb +131 -0
  60. data/lib/object_present.rb +1 -1
  61. data/lib/option_value.rb +1 -1
  62. data/lib/resize_terminal.rb +1 -2
  63. data/lib/saved_assets.rb +1 -1
  64. data/lib/saved_files_matcher.rb +1 -1
  65. data/lib/shell_session.rb +439 -0
  66. data/lib/streams_out.rb +0 -1
  67. data/lib/string_util.rb +11 -1
  68. data/lib/success_result.rb +112 -0
  69. data/lib/text_analyzer.rb +1 -0
  70. data/lib/ww.rb +9 -7
  71. metadata +25 -3
data/lib/menu.src.yml CHANGED
@@ -103,6 +103,12 @@
103
103
  :default: true
104
104
  :procname: val_as_bool
105
105
 
106
+ - :opt_name: command_substitution_format
107
+ :env_var: MDE_COMMAND_SUBSTITUTION_FORMAT
108
+ :description: command_substitution_format
109
+ :default: '$(%s)'
110
+ :procname: val_as_str
111
+
106
112
  - :opt_name: command_substitution_regexp
107
113
  :env_var: MDE_COMMAND_SUBSTITUTION_REGEXP
108
114
  :description: command_substitution_regexp
@@ -207,12 +213,6 @@
207
213
  :default: "(document_shell)"
208
214
  :procname: val_as_str
209
215
 
210
- - :opt_name: document_load_ux_block_name
211
- :env_var: MDE_DOCUMENT_LOAD_UX_BLOCK_NAME
212
- :description: Name of UX block to load with the document
213
- :default: "\\[.*document_ux.*\\]"
214
- :procname: val_as_str
215
-
216
216
  - :opt_name: document_load_vars_block_name
217
217
  :env_var: MDE_DOCUMENT_LOAD_VARS_BLOCK_NAME
218
218
  :description: Name of Vars block to load with the document
@@ -914,7 +914,9 @@
914
914
  - :opt_name: menu_note_match
915
915
  :env_var: MDE_MENU_NOTE_MATCH
916
916
  :description: Pattern for notes in block selection menu
917
- :default: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
917
+ # 'line' excludes 'indent' and 'trailing'
918
+ # 'text' group matches multiline from variable expansion
919
+ :default: "^(?'indent'[ \t]*)(?'line'(?!/)(?'text'.*))(?'trailing'[ \t]*)?$"
918
920
  :procname: val_as_str
919
921
 
920
922
  - :opt_name: menu_option_back_name
@@ -1661,6 +1663,12 @@
1661
1663
  :default: true
1662
1664
  :procname: val_as_bool
1663
1665
 
1666
+ - :opt_name: variable_expression_format
1667
+ :env_var: MDE_VARIABLE_EXPRESSION_FORMAT
1668
+ :description: variable_expression_format
1669
+ :default: '${%s}'
1670
+ :procname: val_as_str
1671
+
1664
1672
  - :opt_name: variable_expression_regexp
1665
1673
  :env_var: MDE_VARIABLE_EXPRESSION_REGEXP
1666
1674
  :description: variable_expression_regexp
data/lib/menu.yml CHANGED
@@ -84,6 +84,11 @@
84
84
  :arg_name: BOOL
85
85
  :default: true
86
86
  :procname: val_as_bool
87
+ - :opt_name: command_substitution_format
88
+ :env_var: MDE_COMMAND_SUBSTITUTION_FORMAT
89
+ :description: command_substitution_format
90
+ :default: "$(%s)"
91
+ :procname: val_as_str
87
92
  - :opt_name: command_substitution_regexp
88
93
  :env_var: MDE_COMMAND_SUBSTITUTION_REGEXP
89
94
  :description: command_substitution_regexp
@@ -172,11 +177,6 @@
172
177
  :description: Name of shell block to load with the document
173
178
  :default: "(document_shell)"
174
179
  :procname: val_as_str
175
- - :opt_name: document_load_ux_block_name
176
- :env_var: MDE_DOCUMENT_LOAD_UX_BLOCK_NAME
177
- :description: Name of UX block to load with the document
178
- :default: "\\[.*document_ux.*\\]"
179
- :procname: val_as_str
180
180
  - :opt_name: document_load_vars_block_name
181
181
  :env_var: MDE_DOCUMENT_LOAD_VARS_BLOCK_NAME
182
182
  :description: Name of Vars block to load with the document
@@ -772,7 +772,7 @@
772
772
  - :opt_name: menu_note_match
773
773
  :env_var: MDE_MENU_NOTE_MATCH
774
774
  :description: Pattern for notes in block selection menu
775
- :default: "^(?<indent>[ \t]*)(?<line>(?!/)(?<text>.*?)(?<trailing>[ \t]*))?$"
775
+ :default: "^(?'indent'[ \t]*)(?'line'(?!/)(?'text'.*))(?'trailing'[ \t]*)?$"
776
776
  :procname: val_as_str
777
777
  - :opt_name: menu_option_back_name
778
778
  :env_var: MDE_MENU_OPTION_BACK_NAME
@@ -1419,6 +1419,11 @@
1419
1419
  :arg_name: BOOL
1420
1420
  :default: true
1421
1421
  :procname: val_as_bool
1422
+ - :opt_name: variable_expression_format
1423
+ :env_var: MDE_VARIABLE_EXPRESSION_FORMAT
1424
+ :description: variable_expression_format
1425
+ :default: "${%s}"
1426
+ :procname: val_as_str
1422
1427
  - :opt_name: variable_expression_regexp
1423
1428
  :env_var: MDE_VARIABLE_EXPRESSION_REGEXP
1424
1429
  :description: variable_expression_regexp
data/lib/namer.rb CHANGED
@@ -1,4 +1,3 @@
1
- #!/usr/bin/env ruby
2
1
  # frozen_string_literal: true
3
2
 
4
3
  # encoding=utf-8
@@ -10,9 +9,7 @@ class Hash
10
9
  # block name in commands and documents
11
10
  def pub_name(**kwargs)
12
11
  full = fetch(:nickname, nil) || fetch(:oname, nil)
13
- full&.to_s&.pub_name(**kwargs).tap { |ret|
14
- pp [__LINE__, 'Hash.pub_name() ->', ret] if $pd
15
- }
12
+ full&.to_s&.pub_name(**kwargs)
16
13
  end
17
14
  end
18
15
 
@@ -37,8 +34,8 @@ class String
37
34
  self
38
35
  end
39
36
 
40
- trimmed.gsub(pattern, replacement).tap { |ret|
37
+ trimmed.gsub(pattern, replacement).tap do |ret|
41
38
  pp [__LINE__, 'String.pub_name() ->', ret] if $pd
42
- }
39
+ end
43
40
  end
44
41
  end
@@ -0,0 +1,131 @@
1
+ #!/usr/bin/env -S bundle exec ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+
6
+ ##
7
+ # NullResult represents a fallback object returned when a valid result cannot be produced.
8
+ #
9
+ # This class implements the Null Object pattern and can optionally carry additional
10
+ # failure details such as a custom message and a data payload.
11
+ #
12
+ # Example:
13
+ # result = SomeService.call
14
+ #
15
+ # if result.failure?
16
+ # puts "Error: #{result.message}"
17
+ # puts "Details: #{result.data.inspect}" if result.data
18
+ # end
19
+ #
20
+ class NullResult
21
+ ##
22
+ # Initializes a new NullResult.
23
+ #
24
+ # @param message [String] a textual description of the failure (default: 'No valid result available')
25
+ # @param data [Hash, nil] additional structured data conveying details of the failure (default: nil)
26
+ def initialize(message: 'No valid result available', data: nil)
27
+ @message = message
28
+ @data = data
29
+ end
30
+
31
+ ##
32
+ # Indicates that the result is a failure.
33
+ #
34
+ # @return [Boolean] always true
35
+ def failure?
36
+ true
37
+ end
38
+
39
+ ##
40
+ # Indicates that the result is not a success.
41
+ #
42
+ # @return [Boolean] always false
43
+ def success?
44
+ false
45
+ end
46
+
47
+ ##
48
+ # Returns the failure message.
49
+ #
50
+ # @return [String] the message describing the failure
51
+ def message
52
+ @message
53
+ end
54
+
55
+ ##
56
+ # Returns additional failure details.
57
+ #
58
+ # @return [Hash, nil] structured data with failure details
59
+ def data
60
+ @data
61
+ end
62
+
63
+ ##
64
+ # Returns a string representation of the NullResult.
65
+ #
66
+ # @return [String]
67
+ def to_s
68
+ "NullResult(message: #{@message.inspect}, data: #{@data.inspect})"
69
+ end
70
+ end
71
+
72
+ # A default instance for cases where no extra details are required.
73
+ DEFAULT_NULL_RESULT = NullResult.new
74
+
75
+ return unless $PROGRAM_NAME == __FILE__
76
+
77
+ require 'bundler/setup'
78
+ Bundler.require(:default)
79
+
80
+ require 'minitest/autorun'
81
+ require 'mocha/minitest'
82
+
83
+ require_relative 'ww'
84
+
85
+ ##
86
+ # Tests for the NullResult class.
87
+ #
88
+ # This suite verifies that the default and custom initialization
89
+ # of NullResult work as expected and that the public interface
90
+ # (e.g. #message, #data, #success?, #failure?, and #to_s) behaves correctly.
91
+ #
92
+ class NullResultTest < Minitest::Test
93
+ def test_default_instance
94
+ nr = NullResult.new
95
+ assert_equal 'No valid result available', nr.message, 'Default message mismatch'
96
+ assert_nil nr.data, 'Default data should be nil'
97
+ refute nr.success?, 'Default instance should not be a success'
98
+ assert nr.failure?, 'Default instance should be a failure'
99
+ assert_match /NullResult/, nr.to_s, 'to_s should include the class name'
100
+ end
101
+
102
+ def test_custom_message
103
+ custom_message = 'Custom error message'
104
+ nr = NullResult.new(message: custom_message)
105
+ assert_equal custom_message, nr.message, 'Custom message mismatch'
106
+ assert_nil nr.data, 'Data should remain nil when not provided'
107
+ end
108
+
109
+ def test_custom_data
110
+ custom_data = { error: 'invalid', code: 404 }
111
+ nr = NullResult.new(data: custom_data)
112
+ assert_equal custom_data, nr.data, 'Custom data mismatch'
113
+ assert_equal 'No valid result available', nr.message, 'Default message expected'
114
+ end
115
+
116
+ def test_custom_message_and_data
117
+ custom_message = 'Error occurred'
118
+ custom_data = { reason: 'not_found' }
119
+ nr = NullResult.new(message: custom_message, data: custom_data)
120
+ assert_equal custom_message, nr.message, 'Custom message mismatch'
121
+ assert_equal custom_data, nr.data, 'Custom data mismatch'
122
+ end
123
+
124
+ def test_to_s_format
125
+ custom_message = 'Error occurred'
126
+ custom_data = { a: 1, b: 2 }
127
+ nr = NullResult.new(message: custom_message, data: custom_data)
128
+ expected = "NullResult(message: #{custom_message.inspect}, data: #{custom_data.inspect})"
129
+ assert_equal expected, nr.to_s, 'String representation does not match expected format'
130
+ end
131
+ end
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env -S bundle exec ruby
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # encoding=utf-8
data/lib/option_value.rb CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env -S bundle exec ruby
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # encoding=utf-8
@@ -123,8 +123,7 @@ class ResizeTerminalTest < Minitest::Test
123
123
  ENV['LINES'] = '24'
124
124
  response = "\e[999;999H\e[6n\e[24;#{columns}R".dup
125
125
  $stdin.stub(:getch, -> { response.slice!(0) || '' }) do
126
- assert_output("\e7\e[r\e[999;999H\e[6n\e8xterm-256color #{columns}x24\n") do
127
- # assert_output('', '') do
126
+ assert_output(/xterm-256color #{columns}x24$/) do
128
127
  resize_terminal(require_stdout: false)
129
128
  end
130
129
  end
data/lib/saved_assets.rb CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env -S bundle exec ruby
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # encoding=utf-8
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env -S bundle exec ruby
2
2
  # frozen_string_literal: true
3
3
 
4
4
  # encoding=utf-8