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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +33 -23
- data/bats/{block-types.bats → block-type-bash.bats} +0 -25
- data/bats/block-type-link.bats +9 -0
- data/bats/block-type-port.bats +16 -0
- data/bats/block-type-ux-allowed.bats +29 -0
- data/bats/block-type-ux-auto.bats +1 -1
- data/bats/block-type-ux-chained.bats +9 -0
- data/bats/block-type-ux-default.bats +8 -0
- data/bats/block-type-ux-echo-hash.bats +14 -0
- data/bats/block-type-ux-echo.bats +2 -2
- data/bats/block-type-ux-exec.bats +1 -1
- data/bats/block-type-ux-hidden.bats +9 -0
- data/bats/block-type-ux-invalid.bats +8 -0
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/indented-block-type-vars.bats +9 -0
- data/bats/line-decor-dynamic.bats +1 -1
- data/bats/test_helper.bash +9 -2
- data/bats/variable-expansion-multiline.bats +8 -0
- data/bats/variable-expansion.bats +1 -1
- data/docs/dev/block-type-ux-allowed.md +82 -0
- data/docs/dev/block-type-ux-auto.md +2 -1
- data/docs/dev/block-type-ux-chained.md +21 -0
- data/docs/dev/block-type-ux-default.md +42 -0
- data/docs/dev/block-type-ux-echo-hash.md +78 -0
- data/docs/dev/block-type-ux-echo.md +3 -1
- data/docs/dev/block-type-ux-exec.md +1 -0
- data/docs/dev/block-type-ux-hidden.md +21 -0
- data/docs/dev/block-type-ux-invalid.md +5 -0
- data/docs/dev/block-type-ux-require.md +9 -18
- data/docs/dev/indented-block-type-vars.md +6 -0
- data/docs/dev/line-decor-dynamic.md +2 -1
- data/docs/dev/variable-expansion-multiline.md +31 -0
- data/lib/ansi_formatter.rb +0 -1
- data/lib/ansi_string.rb +1 -1
- data/lib/array.rb +0 -1
- data/lib/array_util.rb +0 -1
- data/lib/block_label.rb +1 -1
- data/lib/cached_nested_file_reader.rb +1 -1
- data/lib/constants.rb +18 -0
- data/lib/directory_searcher.rb +1 -1
- data/lib/exceptions.rb +0 -1
- data/lib/fcb.rb +52 -9
- data/lib/filter.rb +1 -2
- data/lib/format_table.rb +1 -0
- data/lib/fout.rb +1 -1
- data/lib/hash.rb +0 -1
- data/lib/hash_delegator.rb +404 -224
- data/lib/link_history.rb +17 -17
- data/lib/logged_struct.rb +429 -0
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +3 -3
- data/lib/mdoc.rb +21 -31
- data/lib/menu.src.yml +15 -7
- data/lib/menu.yml +11 -6
- data/lib/namer.rb +3 -6
- data/lib/null_result.rb +131 -0
- data/lib/object_present.rb +1 -1
- data/lib/option_value.rb +1 -1
- data/lib/resize_terminal.rb +1 -2
- data/lib/saved_assets.rb +1 -1
- data/lib/saved_files_matcher.rb +1 -1
- data/lib/shell_session.rb +439 -0
- data/lib/streams_out.rb +0 -1
- data/lib/string_util.rb +11 -1
- data/lib/success_result.rb +112 -0
- data/lib/text_analyzer.rb +1 -0
- data/lib/ww.rb +9 -7
- 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 | 
            -
               | 
| 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: "^( | 
| 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) | 
| 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  | 
| 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
         | 
    
        data/lib/null_result.rb
    ADDED
    
    | @@ -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
         | 
    
        data/lib/object_present.rb
    CHANGED
    
    
    
        data/lib/option_value.rb
    CHANGED
    
    
    
        data/lib/resize_terminal.rb
    CHANGED
    
    | @@ -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( | 
| 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
    
    
    
        data/lib/saved_files_matcher.rb
    CHANGED