markdown_exec 1.3.9 → 1.4
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/.pryrc +11 -0
- data/.rubocop.yml +15 -1
- data/Gemfile.lock +1 -1
- data/bin/bmde +11 -0
- data/bin/tab_completion.sh +2 -2
- data/examples/linked1.md +13 -13
- data/examples/linked2.md +15 -14
- data/examples/linked3.md +12 -0
- data/lib/block_types.rb +2 -0
- data/lib/colorize.rb +52 -55
- data/lib/filter.rb +3 -3
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +873 -614
- data/lib/mdoc.rb +53 -51
- data/lib/menu.src.yml +19 -1
- data/lib/menu.yml +20 -2
- data/lib/method_sorter.rb +76 -0
- data/lib/sort_yaml_gpt4.rb +32 -0
- metadata +7 -2
    
        data/lib/mdoc.rb
    CHANGED
    
    | @@ -25,6 +25,44 @@ module MarkdownExec | |
| 25 25 | 
             
                  @table = table
         | 
| 26 26 | 
             
                end
         | 
| 27 27 |  | 
| 28 | 
            +
                def collect_block_code_cann(fcb)
         | 
| 29 | 
            +
                  body = fcb[:body].join("\n")
         | 
| 30 | 
            +
                  xcall = fcb[:cann][1..-2]
         | 
| 31 | 
            +
                  mstdin = xcall.match(/<(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
         | 
| 32 | 
            +
                  mstdout = xcall.match(/>(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                  yqcmd = if mstdin[:type]
         | 
| 35 | 
            +
                            "echo \"$#{mstdin[:name]}\" | yq '#{body}'"
         | 
| 36 | 
            +
                          else
         | 
| 37 | 
            +
                            "yq e '#{body}' '#{mstdin[:name]}'"
         | 
| 38 | 
            +
                          end
         | 
| 39 | 
            +
                  if mstdout[:type]
         | 
| 40 | 
            +
                    "export #{mstdout[:name]}=$(#{yqcmd})"
         | 
| 41 | 
            +
                  else
         | 
| 42 | 
            +
                    "#{yqcmd} > '#{mstdout[:name]}'"
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
                end
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                def collect_block_code_shell(fcb)
         | 
| 47 | 
            +
                  # write named variables to block at top of script
         | 
| 48 | 
            +
                  #
         | 
| 49 | 
            +
                  fcb[:body].join(' ').split.compact.map do |key|
         | 
| 50 | 
            +
                    format(opts[:block_type_port_set_format], { key: key, value: ENV.fetch(key, nil) })
         | 
| 51 | 
            +
                  end
         | 
| 52 | 
            +
                end
         | 
| 53 | 
            +
             | 
| 54 | 
            +
                def collect_block_code_stdout(fcb)
         | 
| 55 | 
            +
                  stdout = fcb[:stdout]
         | 
| 56 | 
            +
                  body = fcb[:body].join("\n")
         | 
| 57 | 
            +
                  if stdout[:type]
         | 
| 58 | 
            +
                    %(export #{stdout[:name]}=$(cat <<"EOF"\n#{body}\nEOF\n))
         | 
| 59 | 
            +
                  else
         | 
| 60 | 
            +
                    "cat > '#{stdout[:name]}' <<\"EOF\"\n" \
         | 
| 61 | 
            +
                      "#{body}\n" \
         | 
| 62 | 
            +
                      "EOF\n"
         | 
| 63 | 
            +
                  end
         | 
| 64 | 
            +
                end
         | 
| 65 | 
            +
             | 
| 28 66 | 
             
                # Retrieves code blocks that are required by a specified code block.
         | 
| 29 67 | 
             
                #
         | 
| 30 68 | 
             
                # @param name [String] The name of the code block to start the retrieval from.
         | 
| @@ -56,49 +94,18 @@ module MarkdownExec | |
| 56 94 | 
             
                # @param name [String] The name of the code block to start the collection from.
         | 
| 57 95 | 
             
                # @return [Array<String>] An array of strings containing the collected code blocks.
         | 
| 58 96 | 
             
                #
         | 
| 59 | 
            -
                def collect_recursively_required_code(name)
         | 
| 97 | 
            +
                def collect_recursively_required_code(name, opts: {})
         | 
| 60 98 | 
             
                  code = collect_wrapped_blocks(
         | 
| 61 99 | 
             
                    blocks = collect_recursively_required_blocks(name)
         | 
| 62 100 | 
             
                  ).map do |fcb|
         | 
| 63 | 
            -
                    body = fcb[:body].join("\n")
         | 
| 64 | 
            -
             | 
| 65 101 | 
             
                    if fcb[:cann]
         | 
| 66 | 
            -
                       | 
| 67 | 
            -
                      mstdin = xcall.match(/<(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
         | 
| 68 | 
            -
                      mstdout = xcall.match(/>(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                      yqcmd = if mstdin[:type]
         | 
| 71 | 
            -
                                "echo \"$#{mstdin[:name]}\" | yq '#{body}'"
         | 
| 72 | 
            -
                              else
         | 
| 73 | 
            -
                                "yq e '#{body}' '#{mstdin[:name]}'"
         | 
| 74 | 
            -
                              end
         | 
| 75 | 
            -
                      if mstdout[:type]
         | 
| 76 | 
            -
                        "export #{mstdout[:name]}=$(#{yqcmd})"
         | 
| 77 | 
            -
                      else
         | 
| 78 | 
            -
                        "#{yqcmd} > '#{mstdout[:name]}'"
         | 
| 79 | 
            -
                      end
         | 
| 102 | 
            +
                      collect_block_code_cann(fcb)
         | 
| 80 103 | 
             
                    elsif fcb[:stdout]
         | 
| 81 | 
            -
                       | 
| 82 | 
            -
             | 
| 83 | 
            -
                      if stdout[:type]
         | 
| 84 | 
            -
                        %(export #{stdout[:name]}=$(cat <<"EOF"\n#{body}\nEOF\n))
         | 
| 85 | 
            -
                      else
         | 
| 86 | 
            -
                        "cat > '#{stdout[:name]}' <<\"EOF\"\n" \
         | 
| 87 | 
            -
                          "#{body}\n" \
         | 
| 88 | 
            -
                          "EOF\n"
         | 
| 89 | 
            -
                      end
         | 
| 90 | 
            -
                    # elsif fcb[:shell] == 'opts' || fcb[:shell] == 'vars'
         | 
| 91 | 
            -
                    elsif [BLOCK_TYPE_OPTS, BLOCK_TYPE_VARS].include? fcb[:shell]
         | 
| 104 | 
            +
                      collect_block_code_stdout(fcb)
         | 
| 105 | 
            +
                    elsif [BLOCK_TYPE_LINK, BLOCK_TYPE_OPTS, BLOCK_TYPE_VARS].include? fcb[:shell]
         | 
| 92 106 | 
             
                      nil
         | 
| 93 107 | 
             
                    elsif fcb[:shell] == BLOCK_TYPE_PORT
         | 
| 94 | 
            -
                       | 
| 95 | 
            -
                        # write named variables to block at top of script
         | 
| 96 | 
            -
                        #
         | 
| 97 | 
            -
                        fcb[:body].join(' ').split(' ').compact.map do |key|
         | 
| 98 | 
            -
                          # format(opts[:block_type_include_vars_set_format],
         | 
| 99 | 
            -
                          format(': ${%{key}:=%{value}}', { key: key, value: ENV[key] })
         | 
| 100 | 
            -
                        end
         | 
| 101 | 
            -
                      ### end
         | 
| 108 | 
            +
                      collect_block_code_shell(fcb)
         | 
| 102 109 | 
             
                    else
         | 
| 103 110 | 
             
                      fcb[:body]
         | 
| 104 111 | 
             
                    end
         | 
| @@ -285,29 +292,25 @@ if $PROGRAM_NAME == __FILE__ | |
| 285 292 |  | 
| 286 293 | 
             
                  def test_collect_wrapped_blocks
         | 
| 287 294 | 
             
                    # Test case 1: blocks with wraps
         | 
| 288 | 
            -
                     | 
| 295 | 
            +
                    OpenStruct.new(oname: 'block1')
         | 
| 289 296 |  | 
| 290 297 | 
             
                    assert_equal(%w[{wrap1} a],
         | 
| 291 298 | 
             
                                 @mdoc.collect_wrapped_blocks(
         | 
| 292 299 | 
             
                                   [OpenStruct.new(oname: 'a',
         | 
| 293 | 
            -
             | 
| 294 | 
            -
                                 ).map | 
| 295 | 
            -
                                   block.oname
         | 
| 296 | 
            -
                                 end)
         | 
| 300 | 
            +
                                                   wraps: ['{wrap1}'])]
         | 
| 301 | 
            +
                                 ).map(&:oname))
         | 
| 297 302 |  | 
| 298 303 | 
             
                    assert_equal(%w[{wrap2-before} {wrap2} b {wrap2-after}],
         | 
| 299 304 | 
             
                                 @mdoc.collect_wrapped_blocks(
         | 
| 300 305 | 
             
                                   [OpenStruct.new(oname: 'b',
         | 
| 301 | 
            -
             | 
| 302 | 
            -
                                 ).map | 
| 303 | 
            -
                                   block.oname
         | 
| 304 | 
            -
                                 end)
         | 
| 306 | 
            +
                                                   wraps: ['{wrap2}'])]
         | 
| 307 | 
            +
                                 ).map(&:oname))
         | 
| 305 308 |  | 
| 306 309 | 
             
                    assert_equal(%w[{wrap2-before} {wrap2} {wrap3-before} {wrap3} c {wrap3-after} {wrap2-after}],
         | 
| 307 310 | 
             
                                 @mdoc.collect_wrapped_blocks(
         | 
| 308 | 
            -
                                   [OpenStruct.new( | 
| 309 | 
            -
             | 
| 310 | 
            -
                                 ).map | 
| 311 | 
            +
                                   [OpenStruct.new(oname: 'c',
         | 
| 312 | 
            +
                                                   wraps: %w[{wrap2} {wrap3}])]
         | 
| 313 | 
            +
                                 ).map(&:oname))
         | 
| 311 314 |  | 
| 312 315 | 
             
                    # Test case 2: blocks with no wraps
         | 
| 313 316 | 
             
                    blocks = @mdoc.collect_wrapped_blocks([])
         | 
| @@ -316,9 +319,8 @@ if $PROGRAM_NAME == __FILE__ | |
| 316 319 | 
             
                    # Test case 3: blocks with missing wraps
         | 
| 317 320 | 
             
                    assert_equal(
         | 
| 318 321 | 
             
                      %w[block4],
         | 
| 319 | 
            -
                      @mdoc.collect_wrapped_blocks([OpenStruct.new(oname: 'block4', | 
| 320 | 
            -
             | 
| 321 | 
            -
                      end
         | 
| 322 | 
            +
                      @mdoc.collect_wrapped_blocks([OpenStruct.new(oname: 'block4',
         | 
| 323 | 
            +
                                                                   wraps: ['wrap4'])]).map(&:oname)
         | 
| 322 324 | 
             
                    )
         | 
| 323 325 | 
             
                  end
         | 
| 324 326 | 
             
                end
         | 
    
        data/lib/menu.src.yml
    CHANGED
    
    | @@ -51,6 +51,10 @@ | |
| 51 51 | 
             
              :env_var: MDE_BLOCK_STDOUT_SCAN
         | 
| 52 52 | 
             
              :opt_name: block_stdout_scan
         | 
| 53 53 | 
             
              :procname: val_as_str
         | 
| 54 | 
            +
            - :default: ": ${%{key}:=%{value}}"
         | 
| 55 | 
            +
              :env_var: MDE_BLOCK_TYPE_PORT_SET_FORMAT
         | 
| 56 | 
            +
              :opt_name: block_type_port_set_format
         | 
| 57 | 
            +
              :procname: val_as_str
         | 
| 54 58 | 
             
            - :arg_name: PATH
         | 
| 55 59 | 
             
              :default: "."
         | 
| 56 60 | 
             
              :description: Read configuration file
         | 
| @@ -129,10 +133,14 @@ | |
| 129 133 | 
             
              :env_var: MDE_HIDE_BLOCKS_BY_NAME
         | 
| 130 134 | 
             
              :opt_name: hide_blocks_by_name
         | 
| 131 135 | 
             
              :procname: val_as_bool
         | 
| 132 | 
            -
            - :default: " | 
| 136 | 
            +
            - :default: "|"
         | 
| 133 137 | 
             
              :env_var: MDE_HISTORY_DOCUMENT_SEPARATOR
         | 
| 134 138 | 
             
              :opt_name: history_document_separator
         | 
| 135 139 | 
             
              :procname: val_as_str
         | 
| 140 | 
            +
            - :default: "&"
         | 
| 141 | 
            +
              :env_var: MDE_HISTORY_PROPERTY_SEPARATOR
         | 
| 142 | 
            +
              :opt_name: history_property_separator
         | 
| 143 | 
            +
              :procname: val_as_str
         | 
| 136 144 | 
             
            - :default: "^ *@import (.+)$"
         | 
| 137 145 | 
             
              :env_var: MDE_IMPORT_PATTERN
         | 
| 138 146 | 
             
              :opt_name: import_pattern
         | 
| @@ -244,6 +252,16 @@ | |
| 244 252 | 
             
              :env_var: MDE_MENU_LINK_COLOR
         | 
| 245 253 | 
             
              :opt_name: menu_link_color
         | 
| 246 254 | 
             
              :procname: val_as_str
         | 
| 255 | 
            +
            - :default: "* Back"
         | 
| 256 | 
            +
              :description: Text for Back option
         | 
| 257 | 
            +
              :env_var: MDE_MENU_OPTION_BACK_NAME
         | 
| 258 | 
            +
              :opt_name: menu_option_back_name
         | 
| 259 | 
            +
              :procname: val_as_str
         | 
| 260 | 
            +
            - :default: "* Exit"
         | 
| 261 | 
            +
              :description: Text for Exit option
         | 
| 262 | 
            +
              :env_var: MDE_MENU_OPTION_EXIT_NAME
         | 
| 263 | 
            +
              :opt_name: menu_option_exit_name
         | 
| 264 | 
            +
              :procname: val_as_str
         | 
| 247 265 | 
             
            - :default: blue
         | 
| 248 266 | 
             
              :description: Color of menu opts
         | 
| 249 267 | 
             
              :env_var: MDE_MENU_OPTS_COLOR
         | 
    
        data/lib/menu.yml
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            # MDE - Markdown Executor (1. | 
| 1 | 
            +
            # MDE - Markdown Executor (1.4)
         | 
| 2 2 | 
             
            ---
         | 
| 3 3 | 
             
            - :description: Show current configuration values
         | 
| 4 4 | 
             
              :procname: show_config
         | 
| @@ -52,6 +52,10 @@ | |
| 52 52 | 
             
              :env_var: MDE_BLOCK_STDOUT_SCAN
         | 
| 53 53 | 
             
              :opt_name: block_stdout_scan
         | 
| 54 54 | 
             
              :procname: val_as_str
         | 
| 55 | 
            +
            - :default: ": ${%{key}:=%{value}}"
         | 
| 56 | 
            +
              :env_var: MDE_BLOCK_TYPE_PORT_SET_FORMAT
         | 
| 57 | 
            +
              :opt_name: block_type_port_set_format
         | 
| 58 | 
            +
              :procname: val_as_str
         | 
| 55 59 | 
             
            - :arg_name: PATH
         | 
| 56 60 | 
             
              :default: "."
         | 
| 57 61 | 
             
              :description: Read configuration file
         | 
| @@ -130,10 +134,14 @@ | |
| 130 134 | 
             
              :env_var: MDE_HIDE_BLOCKS_BY_NAME
         | 
| 131 135 | 
             
              :opt_name: hide_blocks_by_name
         | 
| 132 136 | 
             
              :procname: val_as_bool
         | 
| 133 | 
            -
            - :default: " | 
| 137 | 
            +
            - :default: "|"
         | 
| 134 138 | 
             
              :env_var: MDE_HISTORY_DOCUMENT_SEPARATOR
         | 
| 135 139 | 
             
              :opt_name: history_document_separator
         | 
| 136 140 | 
             
              :procname: val_as_str
         | 
| 141 | 
            +
            - :default: "&"
         | 
| 142 | 
            +
              :env_var: MDE_HISTORY_PROPERTY_SEPARATOR
         | 
| 143 | 
            +
              :opt_name: history_property_separator
         | 
| 144 | 
            +
              :procname: val_as_str
         | 
| 137 145 | 
             
            - :default: "^ *@import (.+)$"
         | 
| 138 146 | 
             
              :env_var: MDE_IMPORT_PATTERN
         | 
| 139 147 | 
             
              :opt_name: import_pattern
         | 
| @@ -245,6 +253,16 @@ | |
| 245 253 | 
             
              :env_var: MDE_MENU_LINK_COLOR
         | 
| 246 254 | 
             
              :opt_name: menu_link_color
         | 
| 247 255 | 
             
              :procname: val_as_str
         | 
| 256 | 
            +
            - :default: "* Back"
         | 
| 257 | 
            +
              :description: Text for Back option
         | 
| 258 | 
            +
              :env_var: MDE_MENU_OPTION_BACK_NAME
         | 
| 259 | 
            +
              :opt_name: menu_option_back_name
         | 
| 260 | 
            +
              :procname: val_as_str
         | 
| 261 | 
            +
            - :default: "* Exit"
         | 
| 262 | 
            +
              :description: Text for Exit option
         | 
| 263 | 
            +
              :env_var: MDE_MENU_OPTION_EXIT_NAME
         | 
| 264 | 
            +
              :opt_name: menu_option_exit_name
         | 
| 265 | 
            +
              :procname: val_as_str
         | 
| 248 266 | 
             
            - :default: blue
         | 
| 249 267 | 
             
              :description: Color of menu opts
         | 
| 250 268 | 
             
              :env_var: MDE_MENU_OPTS_COLOR
         | 
| @@ -0,0 +1,76 @@ | |
| 1 | 
            +
            require 'ripper'
         | 
| 2 | 
            +
            require 'parser/current'
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            class MethodSorter
         | 
| 5 | 
            +
              def initialize(file_path)
         | 
| 6 | 
            +
                @file_path = file_path
         | 
| 7 | 
            +
              end
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              def sort
         | 
| 10 | 
            +
                file_contents = File.read(@file_path)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                ast = Parser::CurrentRuby.parse(file_contents)
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                # Find the class node
         | 
| 15 | 
            +
                class_node = ast.children.find { |node| node.type == :class }
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                method_nodes = []
         | 
| 18 | 
            +
             | 
| 19 | 
            +
                # Look for method def nodes within each child node 
         | 
| 20 | 
            +
                class_node.children.compact.each do |child|
         | 
| 21 | 
            +
                  if child.type == :begin
         | 
| 22 | 
            +
                    method_nodes += child.children.select {|n| n.type == :def}
         | 
| 23 | 
            +
                  end
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                # Sort and process method nodes
         | 
| 27 | 
            +
                # class_node = ast.children.find { |node| node.type == :class }
         | 
| 28 | 
            +
                # unless class_node
         | 
| 29 | 
            +
                #   puts "No class node found in #{@file_path}"
         | 
| 30 | 
            +
                #   return
         | 
| 31 | 
            +
                # end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                # method_nodes = class_node.children.compact.select { |node| 
         | 
| 34 | 
            +
                #   node.type == :def
         | 
| 35 | 
            +
                # }    
         | 
| 36 | 
            +
             | 
| 37 | 
            +
                sorted_methods = method_nodes.sort_by{ |n| n.children[0].to_s }
         | 
| 38 | 
            +
                ripper = Ripper.sexp(file_contents)
         | 
| 39 | 
            +
                lines = ripper.each_with_index.map{|sexp, index| [sexp, index] }
         | 
| 40 | 
            +
                
         | 
| 41 | 
            +
                method_ranges = get_method_ranges(lines, method_nodes)
         | 
| 42 | 
            +
                
         | 
| 43 | 
            +
                result = replace_method_ranges(lines, method_ranges, sorted_methods)
         | 
| 44 | 
            +
                
         | 
| 45 | 
            +
                puts result.compact.select{|v|v.is_a? String}.join("\n")
         | 
| 46 | 
            +
                # File.write(@file_path, result.join)
         | 
| 47 | 
            +
              end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
              private
         | 
| 50 | 
            +
              
         | 
| 51 | 
            +
              def get_method_ranges(lines, method_nodes)
         | 
| 52 | 
            +
                method_nodes.map do |method_node|
         | 
| 53 | 
            +
                  start_line = method_node.loc.line - 1
         | 
| 54 | 
            +
                  end_line = start_line
         | 
| 55 | 
            +
                  
         | 
| 56 | 
            +
                  while end_line < lines.size && lines[end_line][0] !~ /^end/
         | 
| 57 | 
            +
                    end_line += 1
         | 
| 58 | 
            +
                  end
         | 
| 59 | 
            +
                  
         | 
| 60 | 
            +
                  (start_line..end_line)
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
              end
         | 
| 63 | 
            +
              
         | 
| 64 | 
            +
              def replace_method_ranges(lines, ranges, sorted_methods)
         | 
| 65 | 
            +
                result = lines.dup
         | 
| 66 | 
            +
                
         | 
| 67 | 
            +
                ranges.each_with_index do |range, index|
         | 
| 68 | 
            +
                  result[range] = sorted_methods[index].loc.expression.source.split("\n") 
         | 
| 69 | 
            +
                end
         | 
| 70 | 
            +
                
         | 
| 71 | 
            +
                result
         | 
| 72 | 
            +
              end
         | 
| 73 | 
            +
            end
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            sorter = MethodSorter.new(ARGV[0])
         | 
| 76 | 
            +
            sorter.sort
         | 
| @@ -0,0 +1,32 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'yaml'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            def sort_yaml(input_yaml)
         | 
| 6 | 
            +
              # Parse the input YAML
         | 
| 7 | 
            +
              data = YAML.load(input_yaml)
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              # Ensure data is an array of hashes
         | 
| 10 | 
            +
              unless data.is_a?(Array) && data.all? { |item| item.is_a?(Hash) }
         | 
| 11 | 
            +
                raise ArgumentError, 'Input YAML must be an array of hashes.'
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              # Sort items by 'opt_name' values
         | 
| 15 | 
            +
              sorted_data = data.sort_by do |item|
         | 
| 16 | 
            +
                (item[:opt_name] || item[:long_name] || item[:short_name]).to_s
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
             | 
| 19 | 
            +
              # Sort keys in each item
         | 
| 20 | 
            +
              sorted_data.each do |item|
         | 
| 21 | 
            +
                item.replace(item.sort.to_h)
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              # Convert the sorted data back to YAML and write to stdout
         | 
| 25 | 
            +
              puts YAML.dump(sorted_data).gsub("\n-", "\n\n-")
         | 
| 26 | 
            +
            end
         | 
| 27 | 
            +
             | 
| 28 | 
            +
            # Read YAML from stdin
         | 
| 29 | 
            +
            input_yaml = $stdin.read
         | 
| 30 | 
            +
             | 
| 31 | 
            +
            # Call the function with input YAML
         | 
| 32 | 
            +
            sort_yaml(input_yaml)
         | 
    
        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: 1. | 
| 4 | 
            +
              version: '1.4'
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Fareed Stevenson
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2023-10- | 
| 11 | 
            +
            date: 2023-10-31 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: clipboard
         | 
| @@ -91,6 +91,7 @@ executables: | |
| 91 91 | 
             
            extensions: []
         | 
| 92 92 | 
             
            extra_rdoc_files: []
         | 
| 93 93 | 
             
            files:
         | 
| 94 | 
            +
            - ".pryrc"
         | 
| 94 95 | 
             
            - ".reek"
         | 
| 95 96 | 
             
            - ".rubocop.yml"
         | 
| 96 97 | 
             
            - CHANGELOG.md
         | 
| @@ -105,6 +106,7 @@ files: | |
| 105 106 | 
             
            - assets/output_of_execution.png
         | 
| 106 107 | 
             
            - assets/select_a_block.png
         | 
| 107 108 | 
             
            - assets/select_a_file.png
         | 
| 109 | 
            +
            - bin/bmde
         | 
| 108 110 | 
             
            - bin/colorize_env_vars.sh
         | 
| 109 111 | 
             
            - bin/console
         | 
| 110 112 | 
             
            - bin/mde
         | 
| @@ -118,6 +120,7 @@ files: | |
| 118 120 | 
             
            - examples/infile_config.md
         | 
| 119 121 | 
             
            - examples/linked1.md
         | 
| 120 122 | 
             
            - examples/linked2.md
         | 
| 123 | 
            +
            - examples/linked3.md
         | 
| 121 124 | 
             
            - examples/opts.md
         | 
| 122 125 | 
             
            - examples/pass-through.md
         | 
| 123 126 | 
             
            - examples/plant.md
         | 
| @@ -138,6 +141,7 @@ files: | |
| 138 141 | 
             
            - lib/mdoc.rb
         | 
| 139 142 | 
             
            - lib/menu.src.yml
         | 
| 140 143 | 
             
            - lib/menu.yml
         | 
| 144 | 
            +
            - lib/method_sorter.rb
         | 
| 141 145 | 
             
            - lib/object_present.rb
         | 
| 142 146 | 
             
            - lib/option_value.rb
         | 
| 143 147 | 
             
            - lib/regexp.rb
         | 
| @@ -145,6 +149,7 @@ files: | |
| 145 149 | 
             
            - lib/saved_assets.rb
         | 
| 146 150 | 
             
            - lib/saved_files_matcher.rb
         | 
| 147 151 | 
             
            - lib/shared.rb
         | 
| 152 | 
            +
            - lib/sort_yaml_gpt4.rb
         | 
| 148 153 | 
             
            - lib/tap.rb
         | 
| 149 154 | 
             
            homepage: https://rubygems.org/gems/markdown_exec
         | 
| 150 155 | 
             
            licenses:
         |