markdown_exec 1.3.8 → 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.
@@ -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.3.8
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-20 00:00:00.000000000 Z
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,28 +106,42 @@ 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
110
+ - bin/colorize_env_vars.sh
108
111
  - bin/console
109
112
  - bin/mde
110
113
  - bin/setup
111
114
  - bin/tab_completion.sh
112
115
  - bin/tab_completion.sh.erb
116
+ - examples/duplicate_block.md
117
+ - examples/import0.md
118
+ - examples/import1.md
119
+ - examples/include.md
120
+ - examples/infile_config.md
121
+ - examples/linked1.md
122
+ - examples/linked2.md
123
+ - examples/linked3.md
124
+ - examples/opts.md
125
+ - examples/pass-through.md
126
+ - examples/plant.md
127
+ - examples/port.md
128
+ - examples/vars.md
129
+ - examples/wrap.md
113
130
  - lib/block_label.rb
131
+ - lib/block_types.rb
114
132
  - lib/cached_nested_file_reader.rb
115
133
  - lib/cli.rb
116
134
  - lib/colorize.rb
117
135
  - lib/env.rb
118
- - lib/env_opts.rb
119
136
  - lib/environment_opt_parse.rb
120
137
  - lib/fcb.rb
121
138
  - lib/filter.rb
122
- - lib/markdown_block_manager.rb
123
139
  - lib/markdown_exec.rb
124
140
  - lib/markdown_exec/version.rb
125
141
  - lib/mdoc.rb
126
142
  - lib/menu.src.yml
127
143
  - lib/menu.yml
128
- - lib/menu_options.rb
129
- - lib/menu_options.yml
144
+ - lib/method_sorter.rb
130
145
  - lib/object_present.rb
131
146
  - lib/option_value.rb
132
147
  - lib/regexp.rb
@@ -134,6 +149,7 @@ files:
134
149
  - lib/saved_assets.rb
135
150
  - lib/saved_files_matcher.rb
136
151
  - lib/shared.rb
152
+ - lib/sort_yaml_gpt4.rb
137
153
  - lib/tap.rb
138
154
  homepage: https://rubygems.org/gems/markdown_exec
139
155
  licenses:
data/lib/env_opts.rb DELETED
@@ -1,242 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # encoding=utf-8
4
-
5
- require_relative 'tap'
6
-
7
- include Tap #; tap_config
8
-
9
- # define options with initial values
10
- # option to read value from environmnt variables
11
- # option to cast input values
12
- # value priority: default < environment < argument
13
- #
14
- # :reek:TooManyMethods
15
- class EnvOpts
16
- attr_reader :opts, :values
17
-
18
- def initialize(opts_raw = {}, argv = ARGV)
19
- @opts = {}
20
- @values = {}
21
- add_options(opts_raw)
22
- # parse(argv, &block) if block_given?
23
- block_given? ? parse(argv, &block) : parse(argv)
24
-
25
- self # rubocop:disable Lint/Void
26
- end
27
-
28
- # add options to menu
29
- # calculate help text
30
- #
31
- # :reek:NestedIterators
32
- def add_options(opts_raw)
33
- return self if opts_raw.nil?
34
-
35
- help_rows = opts_raw.map do |key, opt_raw|
36
- opt_name = key_name_to_option_name(key)
37
-
38
- # set_per_options(opt_name, opt_raw)
39
- @opts[opt_name] = (opt_raw ||= {})
40
- set_key_value_as_cast(opt_name, EnvOpts.optdefault(opt_raw))
41
- set_key_value_per_environment_as_cast(opt_name, opt_raw)
42
-
43
- [
44
- [20, '-', "--#{opt_name}"],
45
- [16, '-',
46
- if @opts[opt_name][:env].present?
47
- option_name_to_environment_name(opt_name, @opts[opt_name])
48
- else
49
- ''
50
- end],
51
- # [24, '-', get_environment_value_from_option(opt_name, @opts[opt_name])],
52
- [24, '-', @opts[opt_name][:default]],
53
- [6, '-', if (fixed = opt_raw.fetch(:fixed, nil)).nil?
54
- ":#{option_cast(@opts[opt_name])}"
55
- else
56
- fixed.to_s
57
- end]
58
- ]
59
- end
60
-
61
- max_widths = help_rows.reduce([0, 0, 0, 0]) do |memo, vals|
62
- vals.map.with_index do |val, ind|
63
- [memo[ind], val[2].to_s.length].max
64
- end
65
- end
66
-
67
- @values['help'] = help_rows.map do |row|
68
- row.map.with_index do |cell, ind|
69
- format("%#{cell[1]}#{max_widths[ind]}s", cell[2])
70
- end.join(' ')
71
- end.join("\n")
72
-
73
- self
74
- end
75
-
76
- # accept :d or :default option
77
- #
78
- def self.optdefault(opt_raw)
79
- return opt_raw[:d] unless opt_raw[:d].nil?
80
-
81
- opt_raw[:default]
82
- end
83
-
84
- def output_help
85
- puts @values['help']
86
- end
87
-
88
- # process arguments as mostly pairs of option name and value
89
- #
90
- def parse(argv = ARGV)
91
- return self if argv.nil? || !(argv&.count || 0).positive?
92
-
93
- args_ind = 0
94
- while args_ind < argv.count
95
- args_consumed = 0
96
- arg = argv.fetch(args_ind, '')
97
- if arg.start_with? '--'
98
- opt_name = arg[2..-1]
99
- args_consumed = consume_arguments(opt_name,
100
- argv.fetch(args_ind + 1, nil))
101
- end
102
-
103
- if args_consumed.zero?
104
- if arg == '--help'
105
- output_help
106
- exit
107
- elsif block_given?
108
- yield 'NAO', [arg]
109
- args_consumed = 1
110
- else
111
- warn "Invalid argument: #{arg.inspect} in #{argv.inspect}"
112
- exit 1
113
- end
114
- end
115
-
116
- args_ind += args_consumed
117
- end
118
-
119
- self
120
- end
121
-
122
- # set option current values per environment values
123
- #
124
- def options_per_environment_as_cast(opts_raw)
125
- return self if opts_raw.nil?
126
-
127
- opts_raw.each do |key, opt_raw|
128
- set_key_value_per_environment_as_cast(key_name_to_option_name(key),
129
- opt_raw)
130
- end
131
-
132
- self
133
- end
134
-
135
- # symbol name to option name
136
- # option names use hyphens
137
- #
138
- def self.symbol_name_to_option_name(name)
139
- name.to_s.gsub('_', '-')
140
- end
141
-
142
- private
143
-
144
- # convert key name or symbol to an option name
145
- #
146
- def key_name_to_option_name(key)
147
- (key.is_a?(Symbol) ? EnvOpts.symbol_name_to_option_name(key) : key)
148
- end
149
-
150
- # get cast of environment variable
151
- #
152
- def option_cast(opt_raw)
153
- (opt_raw[:cast].present? ? opt_raw[:cast].to_s : 'to_s')
154
- end
155
-
156
- # update value for named option
157
- # return number of arguments used
158
- #
159
- def consume_arguments(opt_name, value)
160
- return 0 if (opt_raw = @opts.fetch(opt_name, nil)).nil?
161
-
162
- return 0 unless opt_raw.fetch(:option, true)
163
-
164
- if !(fixed = opt_raw.fetch(:fixed, nil)).nil?
165
- set_key_value_as_cast(opt_name, fixed)
166
- 1
167
- elsif value.nil?
168
- 0
169
- else
170
- set_key_value_as_cast(opt_name, value)
171
- 2
172
- end
173
- end
174
-
175
- # option names use hyphens
176
- #
177
- def method_name_to_option_name(name)
178
- name.to_s.gsub('_', '-')
179
- end
180
-
181
- # read and write options using the option name as a method
182
- #
183
- def method_missing(method_name, *args)
184
- if method_name.to_s.end_with?('=')
185
- value = args.first
186
- name = method_name_to_option_name(method_name.to_s[0..-2])
187
- set_key_value_as_cast(name, value)
188
- else
189
- @values[method_name_to_option_name(method_name)]
190
- end
191
- end
192
-
193
- # option name to environment name
194
- # if true or empty, compute from option name
195
- #
196
- def option_name_to_environment_name(opt_name, opt_raw)
197
- case env_name = opt_raw.fetch(:env, '')
198
- when true, ''
199
- "#{@values['env-prefix']}#{opt_name.upcase.gsub('-', '_')}"
200
- else
201
- env_name
202
- end
203
- end
204
-
205
- # get environment value from option
206
- #
207
- def get_environment_value_from_option(opt_name, opt_raw)
208
- ENV.fetch(option_name_to_environment_name(opt_name, opt_raw),
209
- nil)
210
- end
211
-
212
- # option names are available as methods
213
- #
214
- # :reek:BooleanParameter
215
- def respond_to_missing?(method_name, include_private = false)
216
- (@opts.keys.include?(method_name_to_option_name(method_name)) || super)
217
- end
218
-
219
- def set_key_value_as_cast(key, value)
220
- opt = @opts[key]
221
- set_key_value_raw(key, (opt[:cast] ? value.send(opt[:cast]) : value))
222
- end
223
-
224
- # set key value_per environment as cast
225
- #
226
- def set_key_value_per_environment_as_cast(key, opt_raw)
227
- return if opt_raw[:env].nil?
228
-
229
- value = get_environment_value_from_option(key, opt_raw)
230
-
231
- return unless value
232
-
233
- set_key_value_as_cast(key,
234
- opt_raw[:cast] ? value.send(opt_raw[:cast]) : value)
235
- end
236
-
237
- # set key value (raw)
238
- #
239
- def set_key_value_raw(key, value)
240
- @values[key] = value
241
- end
242
- end
@@ -1,64 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # frozen_string_literal: true
3
-
4
- # encoding=utf-8
5
-
6
- require_relative 'filter'
7
-
8
- module MarkdownExec
9
- ##
10
- # MarkdownBlockManager represents an imported markdown document.
11
- #
12
- # It provides methods to extract and manipulate specific sections
13
- # of the document, such as code blocks. It also supports recursion
14
- # to fetch related or dependent blocks.
15
- #
16
- class MarkdownBlockManager
17
- attr_reader :block_table
18
-
19
- # initialize
20
- #
21
- # Initializes an instance of MarkdownBlockManager with the given block table.
22
- #
23
- # @param block_table [Array<Hash>] An array of hashes representing markdown blocks.
24
- def initialize(block_table)
25
- @block_table = block_table
26
- end
27
-
28
- # get_block
29
- #
30
- # Retrieves a code block by its name.
31
- #
32
- # @param name [String] The name of the code block to retrieve.
33
- # @param default [Hash] The default value to return if the code block is not found.
34
- # @return [Hash] The code block as a hash or the default value if not found.
35
- def get_block(name, default = {})
36
- @block_table.select { |block| block.fetch(:name, '') == name }.fetch(0, default)
37
- end
38
- end
39
- end
40
-
41
- if $PROGRAM_NAME == __FILE__
42
- # require 'bundler/setup'
43
- # Bundler.require(:default)
44
-
45
- require 'minitest/autorun'
46
-
47
- class MarkdownBlockManagerTest < Minitest::Test
48
- def setup
49
- @block_table = [
50
- { name: 'block1', reqs: ['block2'], body: ['code1'] },
51
- { name: 'block2', body: ['code2'] },
52
- { name: 'block3', body: ['code3'] }
53
- ]
54
- @manager = MarkdownExec::MarkdownBlockManager.new(@block_table)
55
- end
56
-
57
- # Test the get_block method
58
- def test_get_block
59
- block = @manager.get_block('block2')
60
- expected_block = { name: 'block2', body: ['code2'] }
61
- assert_equal expected_block, block
62
- end
63
- end
64
- end
data/lib/menu_options.rb DELETED
File without changes
data/lib/menu_options.yml DELETED
File without changes