markdown_exec 1.3.9 → 1.4

Sign up to get free protection for your applications and to get access to all the features.
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
- xcall = fcb[:cann][1..-2]
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
- stdout = fcb[:stdout]
82
- body = fcb[:body].join("\n")
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
- ### if opts[:block_type_include_vars_set_format].present?
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
- block = OpenStruct.new(oname: 'block1')
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
- wraps: ['{wrap1}'])]
294
- ).map do |block|
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
- wraps: ['{wrap2}'])]
302
- ).map do |block|
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( oname: 'c',
309
- wraps: %w[{wrap2} {wrap3}] )]
310
- ).map { |block| block.oname })
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', wraps: ['wrap4'])]).map do |block|
320
- block.oname
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.3.9)
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.3.9
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-29 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,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: