markdown_exec 1.8.4 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c5acb96c20743bda8d745d4dece7997ff6cd5b5474fdeba4b7401474c7500528
4
- data.tar.gz: 8e52cb02c35801816c9472c94112b521b110a758f602fdf0b19c4dd851c23243
3
+ metadata.gz: 4e802d2af4a779aad7091b20ab189a4c324f15f53643880758b7aac76549ba49
4
+ data.tar.gz: 2d6f910706bd10232f8bb87313364f671d3871e06382d57dd6248f07c4e497f2
5
5
  SHA512:
6
- metadata.gz: bb66529f2a2766cb1f8cbdd8b071c02eb29ef0c55e29507576a3cb9a0fc4920093fb03af95ddd480a8f6a189d3a86c4b504315f2faadba173a345d07fd16de8e
7
- data.tar.gz: 19af41e603d32a7acc84151ac4db6e4ae4b746990289cb3c89bf8e436a5bf1c98b2e73814f94b4ee348f6a9bcb3fbce35d195c4588a10965bea9e88c0f486b53
6
+ metadata.gz: c0e4b6ff95bccd281e078eb934d3660c52c28530ae12694c81030b3254de468b24d1d93e2e4d68b4d1163be68de029750930f3de0c3034154b05afde6ac9b42a
7
+ data.tar.gz: 85e260930e3d097e7028ae16cfeb7905fa702accd1fe2bb5b27fdb817d301be10259069be7c7e99f4af5258efbc7be5867d82834cee68bdc8d4e6485592f821e
data/.pryrc CHANGED
@@ -1,3 +1,4 @@
1
+ binding.pry
1
2
  if defined?(PryByebug)
2
3
  Pry.config.pager = false
3
4
  Pry.commands.alias_command 'c', 'continue'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.8.5] - 2023-12-22
4
+
5
+ ### Added
6
+
7
+ - "eval" key for link block type to compute lines to append to the inherited state.
8
+ - Options for dumping data associated with the menu or state.
9
+ - Debug and irb gems.
10
+
3
11
  ## [1.8.4] - 2023-12-15
4
12
 
5
13
  ### Added
data/Gemfile CHANGED
@@ -7,7 +7,9 @@ source 'https://rubygems.org'
7
7
 
8
8
  gemspec
9
9
  gem 'clipboard'
10
+ gem 'debug'
10
11
  gem 'erb'
12
+ gem 'irb', '>= 1.8.0'
11
13
  gem 'mocha', require: false
12
14
  gem 'minitest', require: false
13
15
  gem 'pry-nav'
@@ -22,7 +24,4 @@ gem 'rubocop-rake', require: false
22
24
  gem 'rubocop-rspec', require: false
23
25
  gem 'shellwords'
24
26
  gem 'uri'
25
-
26
- gem 'visual_call_graph'
27
-
28
27
  gem 'yaml', '~> 0.2.1'
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- markdown_exec (1.8.4)
4
+ markdown_exec (1.8.5)
5
5
  clipboard (~> 1.3.6)
6
6
  open3 (~> 0.1.1)
7
7
  optparse (~> 0.1.1)
@@ -39,6 +39,9 @@ GEM
39
39
  coderay (1.1.3)
40
40
  concurrent-ruby (1.2.2)
41
41
  crass (1.0.6)
42
+ debug (1.9.0)
43
+ irb (~> 1.10)
44
+ reline (>= 0.3.8)
42
45
  debug_inspector (1.1.0)
43
46
  diff-lcs (1.5.0)
44
47
  erb (4.0.3)
@@ -46,6 +49,10 @@ GEM
46
49
  erubi (1.12.0)
47
50
  i18n (1.14.1)
48
51
  concurrent-ruby (~> 1.0)
52
+ io-console (0.7.1)
53
+ irb (1.10.1)
54
+ rdoc
55
+ reline (>= 0.3.8)
49
56
  json (2.6.3)
50
57
  kwalify (0.7.2)
51
58
  language_server-protocol (3.17.0.3)
@@ -74,6 +81,8 @@ GEM
74
81
  pry-stack_explorer (0.6.1)
75
82
  binding_of_caller (~> 1.0)
76
83
  pry (~> 0.13)
84
+ psych (5.1.1.1)
85
+ stringio
77
86
  racc (1.7.1)
78
87
  rack (2.2.8)
79
88
  rack-test (2.1.0)
@@ -94,11 +103,15 @@ GEM
94
103
  zeitwerk (~> 2.5)
95
104
  rainbow (3.1.1)
96
105
  rake (13.0.6)
106
+ rdoc (6.6.2)
107
+ psych (>= 4.0.0)
97
108
  reek (6.1.4)
98
109
  kwalify (~> 0.7.0)
99
110
  parser (~> 3.2.0)
100
111
  rainbow (>= 2.0, < 4.0)
101
112
  regexp_parser (2.8.1)
113
+ reline (0.4.1)
114
+ io-console (~> 0.5)
102
115
  rexml (3.2.6)
103
116
  rspec (3.12.0)
104
117
  rspec-core (~> 3.12.0)
@@ -139,11 +152,10 @@ GEM
139
152
  rubocop (~> 1.33)
140
153
  rubocop-capybara (~> 2.17)
141
154
  rubocop-factory_bot (~> 2.22)
142
- ruby-graphviz (1.2.5)
143
- rexml
144
155
  ruby-progressbar (1.13.0)
145
156
  ruby2_keywords (0.0.5)
146
157
  shellwords (0.1.0)
158
+ stringio (3.1.0)
147
159
  thor (1.2.2)
148
160
  tty-color (0.6.0)
149
161
  tty-cursor (0.7.1)
@@ -159,8 +171,6 @@ GEM
159
171
  concurrent-ruby (~> 1.0)
160
172
  unicode-display_width (2.5.0)
161
173
  uri (0.12.2)
162
- visual_call_graph (0.4.0)
163
- ruby-graphviz (~> 1.2, >= 1.2.0)
164
174
  wisper (2.0.1)
165
175
  yaml (0.2.1)
166
176
  zeitwerk (2.6.12)
@@ -170,7 +180,9 @@ PLATFORMS
170
180
 
171
181
  DEPENDENCIES
172
182
  clipboard
183
+ debug
173
184
  erb
185
+ irb (>= 1.8.0)
174
186
  markdown_exec!
175
187
  minitest
176
188
  mocha
@@ -186,7 +198,6 @@ DEPENDENCIES
186
198
  rubocop-rspec
187
199
  shellwords
188
200
  uri
189
- visual_call_graph
190
201
  yaml (~> 0.2.1)
191
202
 
192
203
  BUNDLED WITH
data/bin/bmde CHANGED
@@ -8,106 +8,4 @@ Bundler.require(:default)
8
8
 
9
9
  require_relative '../lib/markdown_exec'
10
10
 
11
- if true
12
-
13
- MarkdownExec::MarkParse.new.run
14
- else
15
-
16
- def trace_event_properties(tp)
17
- # TracePoint.new(:call, :return, :c_call, :c_return, :raise) do |tp|
18
- # puts "Event information:"
19
- # puts "Event type: #{tp.event}"
20
- # puts "File: #{tp.path}"
21
- # puts "Line: #{tp.lineno}"
22
- # puts "Defined class: #{tp.defined_class}"
23
- # puts "Method ID: #{tp.method_id}"
24
- # puts "Class method ID: #{tp.defined_class} #{tp.method_id}"
25
- # puts "Binding: #{tp.binding.inspect}"
26
- # puts "Return value: #{tp.return_value.inspect}" if [:return, :c_return].include?(tp.event)
27
- puts "Raised exception: #{tp.raised_exception.inspect}" if tp.event == :raise
28
- # puts "---------------------------------"
29
- # binding.pry
30
- # print format("\n%-20.20s %-20.20s % 5.5d %20s %s", tp.method_id, tp.defined_class, tp.lineno, tp.path.split('/').last, caller[1].split('/').last)
31
-
32
- # print format("\n%-20.20s %-30.30s %s", tp.method_id, tp.defined_class, caller[1].split('/').last.split(':', 3)[0..1].join(':'))
33
- # print __LINE__, '.'
34
- return if %i[method_missing present?].include?(tp.method_id)
35
- return unless %r(/markdown_exec/lib/) =~ caller[1]
36
-
37
- if [:return, :c_return].include?(tp.event)
38
- print format("%1.1s %-20.20s %s\n", tp.event, tp.method_id, tp.return_value)
39
- else
40
- print format("%1.1s %-20.20s %-30.30s %20s\n", tp.event, tp.method_id, tp.defined_class, $~.post_match)
41
- end
42
- # end.enable
43
- end
44
-
45
- def start_trace(events = [:call])
46
- trace = TracePoint.new(*events) do |tp|
47
- trace_event_properties(tp)
48
- end
49
-
50
- trace.enable
51
- yield
52
- trace.disable
53
- end
54
-
55
- start_trace([:call, :return]) { MarkdownExec::MarkParse.new.run }
56
-
57
- end
58
-
59
-
60
-
61
- =begin
62
-
63
- To filter what is traced, you can pass any of the following as events:
64
-
65
- :line
66
- execute an expression or statement on a new line
67
-
68
- :class
69
- start a class or module definition
70
-
71
- :end
72
- finish a class or module definition
73
-
74
- :call
75
- call a Ruby method
76
-
77
- :return
78
- return from a Ruby method
79
-
80
- :c_call
81
- call a C-language routine
82
-
83
- :c_return
84
- return from a C-language routine
85
-
86
- :raise
87
- raise an exception
88
-
89
- :b_call
90
- event hook at block entry
91
-
92
- :b_return
93
- event hook at block ending
94
-
95
- :a_call
96
- event hook at all calls (call, b_call, and c_call)
97
-
98
- :a_return
99
- event hook at all returns (return, b_return, and c_return)
100
-
101
- :thread_begin
102
- event hook at thread beginning
103
-
104
- :thread_end
105
- event hook at thread ending
106
-
107
- :fiber_switch
108
- event hook at fiber switch
109
-
110
- :script_compiled
111
- new Ruby code compiled (with eval, load or require)
112
-
113
- =end
11
+ MarkdownExec::MarkParse.new.run
@@ -13,7 +13,7 @@ __filedirs_all()
13
13
  }
14
14
 
15
15
  _mde_echo_version() {
16
- echo "1.8.4"
16
+ echo "1.8.5"
17
17
  }
18
18
 
19
19
  _mde() {
@@ -36,8 +36,12 @@ _mde() {
36
36
 
37
37
  -d) COMPREPLY="0"; return 0 ;;
38
38
 
39
+ --dump-dump-delegate-object) COMPREPLY="0"; return 0 ;;
40
+
39
41
  --dump-blocks-in-file) COMPREPLY="0"; return 0 ;;
40
42
 
43
+ --dump-dump-inherited-lines) COMPREPLY="0"; return 0 ;;
44
+
41
45
  --dump-menu-blocks) COMPREPLY="0"; return 0 ;;
42
46
 
43
47
  --dump-selected-block) COMPREPLY="0"; return 0 ;;
@@ -88,7 +92,7 @@ _mde() {
88
92
  # present matching option names
89
93
  #
90
94
  if [[ ${cur} == -* ]] ; then
91
- opts=("--block-name" "--config" "--debug" "--dump-blocks-in-file" "--dump-menu-blocks" "--dump-selected-block" "--exit" "--filename" "--find" "--help" "--how" "--list-blocks" "--list-count" "--list-default-env" "--list-default-yaml" "--list-docs" "--list-recent-output" "--list-recent-scripts" "--output-execution-summary" "--output-script" "--output-stdout" "--path" "--pwd" "--run-last-script" "--save-executed-script" "--save-execution-output" "--saved-script-folder" "--saved-stdout-folder" "--select-recent-output" "--select-recent-script" "--tab-completions" "--user-must-approve" "--version" "--display-level")
95
+ opts=("--block-name" "--config" "--debug" "--dump-dump-delegate-object" "--dump-blocks-in-file" "--dump-dump-inherited-lines" "--dump-menu-blocks" "--dump-selected-block" "--exit" "--filename" "--find" "--help" "--how" "--list-blocks" "--list-count" "--list-default-env" "--list-default-yaml" "--list-docs" "--list-recent-output" "--list-recent-scripts" "--output-execution-summary" "--output-script" "--output-stdout" "--path" "--pwd" "--run-last-script" "--save-executed-script" "--save-execution-output" "--saved-script-folder" "--saved-stdout-folder" "--select-recent-output" "--select-recent-script" "--tab-completions" "--user-must-approve" "--version" "--display-level")
92
96
  COMPREPLY=( $(compgen -W "$(printf "'%s' " "${opts[@]}")" -- "${cur}") )
93
97
 
94
98
  return 0
@@ -111,8 +115,12 @@ _mde() {
111
115
 
112
116
  -d) COMPREPLY=".BOOL."; return 0 ;;
113
117
 
118
+ --dump-dump-delegate-object) COMPREPLY=".BOOL."; return 0 ;;
119
+
114
120
  --dump-blocks-in-file) COMPREPLY=".BOOL."; return 0 ;;
115
121
 
122
+ --dump-dump-inherited-lines) COMPREPLY=".BOOL."; return 0 ;;
123
+
116
124
  --dump-menu-blocks) COMPREPLY=".BOOL."; return 0 ;;
117
125
 
118
126
  --dump-selected-block) COMPREPLY=".BOOL."; return 0 ;;
@@ -166,4 +174,4 @@ _mde() {
166
174
 
167
175
  complete -o filenames -o nospace -F _mde mde
168
176
  # _mde_echo_version
169
- # echo "Updated: 2023-12-16 00:15:53 UTC"
177
+ # echo "Updated: 2023-12-22 22:55:35 UTC"
@@ -0,0 +1,33 @@
1
+ Demonstrate setting a variable interactively for use in generated scripts.
2
+
3
+ ```opts :(document_options)
4
+ pause_after_script_execution: false
5
+ user_must_approve: false
6
+ ```
7
+
8
+ ::: Set VARIABLE to "A"
9
+
10
+ ```link :set_to_A +(set_to_A)
11
+ block: display_variable
12
+ ```
13
+
14
+ ```bash :(set_to_A)
15
+ VARIABLE=A
16
+ ```
17
+
18
+ ::: Set VARIABLE to "B"
19
+
20
+ ```link :set_to_B +(set_to_B)
21
+ block: display_variable
22
+ ```
23
+
24
+ ```bash :(set_to_B)
25
+ VARIABLE=B
26
+ ```
27
+
28
+ ::: Display value of VARIABLE
29
+
30
+ ```bash :display_variable
31
+ source bin/colorize_env_vars.sh
32
+ colorize_env_vars '' VARIABLE
33
+ ```
data/examples/linked1.md CHANGED
@@ -12,7 +12,7 @@ colorize_env_vars 'vars for page3' PAGE3_VAR_VIA_INHERIT page3_var_via_environme
12
12
  ```
13
13
 
14
14
  ```bash :(vars2)
15
- PAGE2_VAR_VIA_INHERIT=for_page2_from_page1_via_inherited_code_file
15
+ PAGE2_VAR_VIA_INHERIT=for_page2_from_page1_via_inherited_code_blocks
16
16
  ```
17
17
 
18
18
  ```link :(linked2) +(vars2)
data/examples/linked2.md CHANGED
@@ -17,7 +17,7 @@ colorize_env_vars 'vars for page3' PAGE3_VAR_VIA_INHERIT page3_var_via_environme
17
17
  ::: 3. executes block "show_vars" to display the imported PAGE3_VAR_VIA_INHERIT.
18
18
 
19
19
  ```bash :(vars3)
20
- PAGE3_VAR_VIA_INHERIT=for_page3_from_page2_via_inherited_code_file
20
+ PAGE3_VAR_VIA_INHERIT=for_page3_from_page2_via_inherited_code_blocks
21
21
  ```
22
22
 
23
23
  ```link :(linked3) +(vars3)
data/examples/opts.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ```opts :opts1
6
6
  menu_divider_color: yellow
7
- menu_note_match:
7
+ menu_note_match: "^ *(?<line>.+?) *$"
8
8
  menu_task_color: fg_rgb_255_63_255
9
9
  ```
10
10
 
@@ -28,47 +28,6 @@ class AnsiFormatter
28
28
  # "#{line_prefix}#{string_send_color(label, highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n")
29
29
  end
30
30
 
31
- # Formats and highlights a list of data. data are presented with indentation,
32
- # and specific items can be highlighted in a specified color, while others are shown in a plain color.
33
- #
34
- # @param data [Hash] A hash of data, where each key is a dependency name,
35
- # and its value is an array of sub-items.
36
- # @param highlight_color_sym [Symbol] The color method to apply to highlighted items.
37
- # Default is :exception_color_detail.
38
- # @param plain_color_sym [Symbol] The color method for non-highlighted items.
39
- # Default is :menu_chrome_color.
40
- # @param label [String] The label to prefix the list of data with.
41
- # Default is 'data:'.
42
- # @param highlight [Array] An array of items to highlight. Each item in this array will be
43
- # formatted with the specified highlight color.
44
- # @param line_prefix [String] Prefix for each line. Default is ' '.
45
- # @param line_postfix [String] Postfix for each line. Default is ''.
46
- # @param detail_sep [String] Separator for items in the sub-list. Default is ' '.
47
- # @return [String] A formatted string representation of the data with highlighted items.
48
- def format_and_highlight_hash(
49
- data,
50
- highlight_color_sym: :exception_color_detail,
51
- plain_color_sym: :menu_chrome_color,
52
- label: 'Data:',
53
- highlight: [],
54
- line_prefix: ' ',
55
- line_postfix: '',
56
- detail_sep: ' '
57
- )
58
- formatted_deps = data&.map do |dep_name, sub_items|
59
- formatted_sub_items = sub_items.map do |item|
60
- color_sym = highlight.include?(item) ? highlight_color_sym : plain_color_sym
61
- string_send_color(item, color_sym)
62
- end.join(detail_sep)
63
-
64
- "#{line_prefix}- #{string_send_color(dep_name,
65
- highlight.include?(dep_name) ? highlight_color_sym : plain_color_sym)}: #{formatted_sub_items}#{line_postfix}"
66
- end || []
67
-
68
- "#{line_prefix}#{string_send_color(label,
69
- highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n")
70
- end
71
-
72
31
  # Function to scan a string and process its segments based on multiple substrings
73
32
  # @param str [String] The string to scan.
74
33
  # @param substrings [Array<String>] The substrings to match in the string.
@@ -5,6 +5,30 @@
5
5
 
6
6
  require 'find'
7
7
 
8
+ def format_and_highlight_hash(
9
+ data,
10
+ highlight_color_sym: :exception_color_detail,
11
+ plain_color_sym: :menu_chrome_color,
12
+ label: 'Data:',
13
+ highlight: [],
14
+ line_prefix: ' ',
15
+ line_postfix: '',
16
+ key_has_value: ': '
17
+ )
18
+ formatted_deps = data&.map do |key, value|
19
+ color_sym = highlight.include?(key) ? highlight_color_sym : plain_color_sym
20
+ dkey = string_send_color(key, color_sym)
21
+
22
+ "#{line_prefix}#{dkey}#{key_has_value}" \
23
+ "#{string_send_color(value,
24
+ highlight.include?(value) ? highlight_color_sym : plain_color_sym)}: " \
25
+ "#{formatted_sub_items}#{line_postfix}"
26
+ end
27
+
28
+ "#{line_prefix}#{string_send_color(label,
29
+ highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n")
30
+ end
31
+
8
32
  # Formats and highlights a list of dependencies. Dependencies are presented with indentation,
9
33
  # and specific items can be highlighted in a specified color, while others are shown in a plain color.
10
34
  #
@@ -47,6 +71,24 @@ def format_and_highlight_dependencies(
47
71
  end
48
72
  # warn menu_blocks.to_yaml.sub(/^(?:---\n)?/, "MenuBlocks:\n")
49
73
 
74
+ def format_and_highlight_lines(
75
+ lines,
76
+ highlight_color_sym: :exception_color_detail,
77
+ plain_color_sym: :menu_chrome_color,
78
+ label: 'Dependencies:',
79
+ highlight: [],
80
+ line_prefix: ' ',
81
+ line_postfix: ''
82
+ )
83
+ formatted_deps = lines&.map do |item|
84
+ "#{line_prefix}- #{string_send_color(dep_name,
85
+ highlight.include?(dep_name) ? highlight_color_sym : plain_color_sym)}: #{item}#{line_postfix}"
86
+ end || []
87
+
88
+ "#{line_prefix}#{string_send_color(label,
89
+ highlight_color_sym)}#{line_postfix}\n" + formatted_deps.join("\n")
90
+ end
91
+
50
92
  IndexedLine = Struct.new(:index, :line) do
51
93
  def to_s
52
94
  line
@@ -77,7 +119,6 @@ class DirectorySearcher
77
119
  match_dirs = []
78
120
  @paths.each do |path|
79
121
  Find.find(path) do |p|
80
- # p 'search_in_directory_names', p
81
122
  # Find.prune unless @include_subdirectories || path == p
82
123
  match_dirs << p if File.directory?(p) && p.match?(@pattern)
83
124
  end
data/lib/filter.rb CHANGED
@@ -61,15 +61,8 @@ module MarkdownExec
61
61
  # @param name [String] The name of the fenced code block.
62
62
  #
63
63
  def self.apply_name_filters(options, filters, name)
64
- if name.present? && options[:block_name]
65
- if name =~ /#{options[:block_name]}/
66
- filters[:name_select] = true
67
- filters[:name_exclude] = false
68
- else
69
- filters[:name_exclude] = true
70
- filters[:name_select] = false
71
- end
72
- end
64
+ filters[:name_select] = true
65
+ filters[:name_exclude] = false
73
66
 
74
67
  if name.present? && filters[:name_select].nil? && options[:select_by_name_regex].present?
75
68
  filters[:name_select] =
@@ -239,12 +232,6 @@ if $PROGRAM_NAME == __FILE__
239
232
  assert Filter.fcb_select?(@options, @fcb)
240
233
  end
241
234
 
242
- def test_name_exclude_condition
243
- @options[:block_name] = 'test'
244
- @fcb[:oname] = 'sample'
245
- refute Filter.fcb_select?(@options, @fcb)
246
- end
247
-
248
235
  def test_shell_exclude_condition
249
236
  @options[:exclude_by_shell_regex] = 'exclude_this'
250
237
  @fcb[:shell] = 'exclude_this_shell'
@@ -269,12 +256,6 @@ if $PROGRAM_NAME == __FILE__
269
256
  assert Filter.fcb_select?(@options, @fcb)
270
257
  end
271
258
 
272
- def test_bash_only_condition_false
273
- @options[:bash_only] = true
274
- @fcb[:shell] = 'zsh'
275
- refute Filter.fcb_select?(@options, @fcb)
276
- end
277
-
278
259
  def test_default_case
279
260
  assert Filter.fcb_select?(@options, @fcb)
280
261
  end
@@ -26,6 +26,7 @@ require_relative 'fout'
26
26
  require_relative 'hash'
27
27
  require_relative 'link_history'
28
28
  require_relative 'mdoc'
29
+ require_relative 'regexp'
29
30
  require_relative 'string_util'
30
31
 
31
32
  class String
@@ -296,17 +297,18 @@ module MarkdownExec
296
297
  label_format_below: @delegate_object[:shell_code_label_format_below],
297
298
  block_source: block_source
298
299
  )
300
+ dependencies = (link_state&.inherited_dependencies || {}).merge(required[:dependencies] || {})
299
301
  required[:unmet_dependencies] =
300
302
  (required[:unmet_dependencies] || []) - (link_state&.inherited_block_names || [])
301
303
  if required[:unmet_dependencies].present?
302
304
  ### filter against link_state.inherited_block_names
303
305
 
304
- warn format_and_highlight_dependencies(required[:dependencies],
306
+ warn format_and_highlight_dependencies(dependencies,
305
307
  highlight: required[:unmet_dependencies])
306
308
  runtime_exception(:runtime_exception_error_level,
307
309
  'unmet_dependencies, flag: runtime_exception_error_level', required[:unmet_dependencies])
308
310
  elsif true
309
- warn format_and_highlight_dependencies(required[:dependencies],
311
+ warn format_and_highlight_dependencies(dependencies,
310
312
  highlight: [@delegate_object[:block_name]])
311
313
  end
312
314
 
@@ -388,6 +390,7 @@ module MarkdownExec
388
390
  output_or_approval = @delegate_object[:output_script] || @delegate_object[:user_must_approve]
389
391
  display_required_code(required_lines) if output_or_approval
390
392
  allow_execution = @delegate_object[:user_must_approve] ? prompt_for_user_approval(required_lines) : true
393
+
391
394
  execute_required_lines(required_lines) if allow_execution
392
395
 
393
396
  link_state.block_name = nil
@@ -609,7 +612,10 @@ module MarkdownExec
609
612
  pop_link_history_and_trigger_load
610
613
 
611
614
  elsif selected[:shell] == BlockType::OPTS
612
- update_options_and_trigger_reuse(selected, @menu_base_options, link_state)
615
+ options_state = read_show_options_and_trigger_reuse(selected, link_state)
616
+ @menu_base_options.merge!(options_state.options)
617
+ @delegate_object.merge!(options_state.options)
618
+ options_state.load_file_link_state
613
619
 
614
620
  else
615
621
  compile_execute_bash_and_special_blocks_and_trigger_reuse(mdoc, selected, link_state,
@@ -805,7 +811,7 @@ module MarkdownExec
805
811
 
806
812
  def link_history_push_and_next(
807
813
  curr_block_name:, curr_document_filename:,
808
- inherited_block_names:, inherited_lines:,
814
+ inherited_block_names:, inherited_dependencies:, inherited_lines:,
809
815
  next_block_name:, next_document_filename:,
810
816
  next_load_file:
811
817
  )
@@ -814,6 +820,7 @@ module MarkdownExec
814
820
  block_name: curr_block_name,
815
821
  document_filename: curr_document_filename,
816
822
  inherited_block_names: inherited_block_names,
823
+ inherited_dependencies: inherited_dependencies,
817
824
  inherited_lines: inherited_lines
818
825
  )
819
826
  )
@@ -823,6 +830,7 @@ module MarkdownExec
823
830
  block_name: next_block_name,
824
831
  document_filename: next_document_filename,
825
832
  inherited_block_names: inherited_block_names,
833
+ inherited_dependencies: inherited_dependencies,
826
834
  inherited_lines: inherited_lines
827
835
  )
828
836
  )
@@ -841,7 +849,10 @@ module MarkdownExec
841
849
  block = block_find(all_blocks, :oname, block_name)
842
850
  return unless block
843
851
 
844
- update_options_and_trigger_reuse(block, @delegate_object)
852
+ options_state = read_show_options_and_trigger_reuse(block)
853
+ @menu_base_options.merge!(options_state.options)
854
+ @delegate_object.merge!(options_state.options)
855
+
845
856
  @most_recent_loaded_filename = @delegate_object[:filename]
846
857
  true
847
858
  end
@@ -978,6 +989,25 @@ module MarkdownExec
978
989
  body.any? ? YAML.load(body.join("\n")) : {}
979
990
  end
980
991
 
992
+ def pop_add_current_code_to_head_and_trigger_load(_link_state, block_names, code_lines,
993
+ dependencies)
994
+ pop = @link_history.pop # updatable
995
+ next_link_state = LinkState.new(
996
+ block_name: pop.block_name,
997
+ document_filename: pop.document_filename,
998
+ inherited_block_names:
999
+ (pop.inherited_block_names + block_names).sort.uniq,
1000
+ inherited_dependencies:
1001
+ dependencies.merge(pop.inherited_dependencies || {}), ### merge, not replace, key data
1002
+ inherited_lines:
1003
+ code_merge(pop.inherited_lines, code_lines)
1004
+ )
1005
+ @link_history.push(next_link_state)
1006
+
1007
+ next_link_state.block_name = nil
1008
+ LoadFileLinkState.new(LoadFile::Load, next_link_state)
1009
+ end
1010
+
981
1011
  # This method handles the back-link operation in the Markdown execution context.
982
1012
  # It updates the history state and prepares to load the next block.
983
1013
  #
@@ -986,10 +1016,11 @@ module MarkdownExec
986
1016
  pop = @link_history.pop
987
1017
  peek = @link_history.peek
988
1018
  LoadFileLinkState.new(LoadFile::Load, LinkState.new(
989
- document_filename: pop.document_filename,
990
- inherited_block_names: peek.inherited_block_names,
991
- inherited_lines: peek.inherited_lines
992
- ))
1019
+ document_filename: pop.document_filename,
1020
+ inherited_block_names: peek.inherited_block_names,
1021
+ inherited_dependencies: peek.inherited_dependencies,
1022
+ inherited_lines: peek.inherited_lines
1023
+ ))
993
1024
  end
994
1025
 
995
1026
  def post_execution_process
@@ -1135,21 +1166,52 @@ module MarkdownExec
1135
1166
  )
1136
1167
  code_lines = code_info[:code]
1137
1168
  block_names = code_info[:block_names]
1169
+ dependencies = code_info[:dependencies]
1138
1170
  else
1139
1171
  block_names = []
1140
1172
  code_lines = []
1173
+ dependencies = {}
1141
1174
  end
1142
-
1143
1175
  next_document_filename = link_block_data['file'] || @delegate_object[:filename]
1144
- link_history_push_and_next(
1145
- curr_block_name: selected[:oname],
1146
- curr_document_filename: @delegate_object[:filename],
1147
- inherited_block_names: ((link_state&.inherited_block_names || []) + block_names).sort.uniq,
1148
- inherited_lines: code_merge(link_state&.inherited_lines, code_lines),
1149
- next_block_name: link_block_data['block'] || '',
1150
- next_document_filename: next_document_filename,
1151
- next_load_file: next_document_filename == @delegate_object[:filename] ? LoadFile::Reuse : LoadFile::Load
1152
- )
1176
+
1177
+ # if an eval link block, evaluate code_lines and return its standard output
1178
+ #
1179
+ if link_block_data.fetch('eval', false)
1180
+ all_code = code_merge(link_state&.inherited_lines, code_lines)
1181
+ output = `#{all_code.join("\n")}`.split("\n")
1182
+ label_format_above = @delegate_object[:shell_code_label_format_above]
1183
+ label_format_below = @delegate_object[:shell_code_label_format_below]
1184
+ block_source = { document_filename: link_state&.document_filename }
1185
+
1186
+ code_lines = [label_format_above && format(label_format_above,
1187
+ block_source.merge({ block_name: selected[:oname] }))] +
1188
+ output.map do |line|
1189
+ re = Regexp.new(link_block_data.fetch('pattern', '(?<line>.*)'))
1190
+ if re =~ line
1191
+ re.gsub_format(line, link_block_data.fetch('format', '%{line}'))
1192
+ end
1193
+ end.compact +
1194
+ [label_format_below && format(label_format_below,
1195
+ block_source.merge({ block_name: selected[:oname] }))]
1196
+
1197
+ end
1198
+
1199
+ if link_block_data['return']
1200
+ pop_add_current_code_to_head_and_trigger_load(link_state, block_names, code_lines,
1201
+ dependencies)
1202
+
1203
+ else
1204
+ link_history_push_and_next(
1205
+ curr_block_name: selected[:oname],
1206
+ curr_document_filename: @delegate_object[:filename],
1207
+ inherited_block_names: ((link_state&.inherited_block_names || []) + block_names).sort.uniq,
1208
+ inherited_dependencies: (link_state&.inherited_dependencies || {}).merge(dependencies || {}), ### merge, not replace, key data
1209
+ inherited_lines: code_merge(link_state&.inherited_lines, code_lines),
1210
+ next_block_name: link_block_data['block'] || '',
1211
+ next_document_filename: next_document_filename,
1212
+ next_load_file: next_document_filename == @delegate_object[:filename] ? LoadFile::Reuse : LoadFile::Load
1213
+ )
1214
+ end
1153
1215
  end
1154
1216
 
1155
1217
  # Reads required code blocks from a temporary file specified by an environment variable.
@@ -1229,8 +1291,17 @@ module MarkdownExec
1229
1291
  link_state.block_name = @delegate_object[:block_name] =
1230
1292
  block_name_from_cli ? @cli_block_name : link_state.block_name
1231
1293
 
1294
+ # update @delegate_object and @menu_base_options in auto_load
1295
+ #
1232
1296
  blocks_in_file, menu_blocks, mdoc = mdoc_menu_and_blocks_from_nested_files
1233
1297
 
1298
+ if @delegate_object[:dump_delegate_object]
1299
+ warn format_and_highlight_hash(
1300
+ @delegate_object,
1301
+ label: '@delegate_object'
1302
+ )
1303
+ end
1304
+
1234
1305
  if @delegate_object[:dump_blocks_in_file]
1235
1306
  warn format_and_highlight_dependencies(
1236
1307
  compact_and_index_hash(blocks_in_file),
@@ -1243,6 +1314,12 @@ module MarkdownExec
1243
1314
  label: 'menu_blocks'
1244
1315
  )
1245
1316
  end
1317
+ if @delegate_object[:dump_inherited_lines]
1318
+ warn format_and_highlight_lines(
1319
+ link_state.inherited_lines,
1320
+ label: 'inherited_lines'
1321
+ )
1322
+ end
1246
1323
 
1247
1324
  block_state = command_or_user_selected_block(blocks_in_file,
1248
1325
  menu_blocks, menu_default_dname)
@@ -1266,6 +1343,7 @@ module MarkdownExec
1266
1343
  )
1267
1344
  load_file = load_file_link_state.load_file
1268
1345
  link_state = load_file_link_state.link_state
1346
+
1269
1347
  # if the same menu is being displayed, collect the display name of the selected menu item for use as the default item
1270
1348
  menu_default_dname = load_file == LoadFile::Load ? nil : block_state.block[:dname]
1271
1349
 
@@ -1406,12 +1484,6 @@ module MarkdownExec
1406
1484
  )
1407
1485
  end
1408
1486
 
1409
- def update_delegate_and_target(key, value, tgt2)
1410
- sym_key = key.to_sym
1411
- @delegate_object[sym_key] = value
1412
- tgt2[sym_key] = value if tgt2
1413
- end
1414
-
1415
1487
  # Updates the hierarchy of document headings based on the given line.
1416
1488
  # Utilizes regular expressions to identify heading levels.
1417
1489
  # @param line [String] The line of text to check for headings.
@@ -1487,6 +1559,10 @@ module MarkdownExec
1487
1559
  # add line if it is depth 0 or option allows it
1488
1560
  #
1489
1561
  yield_line_if_selected(line, selected_messages, &block)
1562
+
1563
+ else
1564
+ # 'rejected'
1565
+
1490
1566
  end
1491
1567
  end
1492
1568
 
@@ -1509,14 +1585,21 @@ module MarkdownExec
1509
1585
  # @param selected [Hash] Selected item from the menu containing a YAML body.
1510
1586
  # @param tgt2 [Hash, nil] An optional target hash to update with YAML data.
1511
1587
  # @return [LoadFileLinkState] An instance indicating the next action for loading files.
1512
- def update_options_and_trigger_reuse(selected, tgt2 = nil, link_state = LinkState.new)
1588
+ def read_show_options_and_trigger_reuse(selected, link_state = LinkState.new)
1589
+ obj = {}
1513
1590
  data = YAML.load(selected[:body].join("\n"))
1514
1591
  (data || []).each do |key, value|
1515
- update_delegate_and_target(key, value, tgt2)
1592
+ sym_key = key.to_sym
1593
+ obj[sym_key] = value
1594
+
1516
1595
  print_formatted_option(key, value) if @delegate_object[:menu_opts_set_format].present?
1517
1596
  end
1597
+
1518
1598
  link_state.block_name = nil
1519
- LoadFileLinkState.new(LoadFile::Reuse, link_state)
1599
+ OpenStruct.new(options: obj,
1600
+ load_file_link_state: LoadFileLinkState.new(
1601
+ LoadFile::Reuse, link_state
1602
+ ))
1520
1603
  end
1521
1604
 
1522
1605
  def wait_for_stream_processing
@@ -1716,6 +1799,7 @@ if $PROGRAM_NAME == __FILE__
1716
1799
  expected_result = LoadFileLinkState.new(LoadFile::Load,
1717
1800
  LinkState.new(block_name: 'sample_block',
1718
1801
  document_filename: 'sample_file',
1802
+ inherited_dependencies: {},
1719
1803
  inherited_lines: []))
1720
1804
  assert_equal expected_result,
1721
1805
  @hd.push_link_history_and_trigger_load(body, nil, FCB.new(block_name: 'sample_block',
@@ -2238,40 +2322,6 @@ if $PROGRAM_NAME == __FILE__
2238
2322
  end
2239
2323
  end
2240
2324
 
2241
- class TestHashDelegatorHandleOptsBlock < Minitest::Test
2242
- def setup
2243
- @hd = HashDelegator.new
2244
- @hd.instance_variable_set(:@delegate_object,
2245
- { menu_opts_set_format: 'Option: %<key>s, Value: %<value>s',
2246
- menu_opts_set_color: :blue })
2247
- @hd.stubs(:string_send_color)
2248
- @hd.stubs(:print)
2249
- end
2250
-
2251
- def test_update_options_and_trigger_reuse
2252
- selected = { body: ['option1: value1'] }
2253
- tgt2 = {}
2254
-
2255
- result = @hd.update_options_and_trigger_reuse(selected, tgt2)
2256
-
2257
- assert_instance_of LoadFileLinkState, result
2258
- assert_equal 'value1',
2259
- @hd.instance_variable_get(:@delegate_object)[:option1]
2260
- assert_equal 'value1', tgt2[:option1]
2261
- end
2262
-
2263
- def test_update_options_and_trigger_reuse_without_format
2264
- selected = { body: ['option2: value2'] }
2265
- @hd.instance_variable_set(:@delegate_object, {})
2266
-
2267
- result = @hd.update_options_and_trigger_reuse(selected)
2268
-
2269
- assert_instance_of LoadFileLinkState, result
2270
- assert_equal 'value2',
2271
- @hd.instance_variable_get(:@delegate_object)[:option2]
2272
- end
2273
- end
2274
-
2275
2325
  # require 'stringio'
2276
2326
 
2277
2327
  class TestHashDelegatorHandleStream < Minitest::Test
@@ -2339,39 +2389,6 @@ if $PROGRAM_NAME == __FILE__
2339
2389
  end
2340
2390
  end
2341
2391
 
2342
- class TestHashDelegatorLoadAutoBlocks < Minitest::Test
2343
- def setup
2344
- @hd = HashDelegator.new
2345
- @hd.stubs(:block_find).returns({})
2346
- @hd.stubs(:update_options_and_trigger_reuse)
2347
- end
2348
-
2349
- def test_load_auto_blocks_with_new_filename
2350
- @hd.instance_variable_set(:@delegate_object, {
2351
- document_load_opts_block_name: 'load_block',
2352
- filename: 'new_file'
2353
- })
2354
- assert @hd.load_auto_blocks([])
2355
- end
2356
-
2357
- def test_load_auto_blocks_with_same_filename
2358
- @hd.instance_variable_set(:@delegate_object, {
2359
- document_load_opts_block_name: 'load_block',
2360
- filename: 'new_file'
2361
- })
2362
- @hd.instance_variable_set(:@most_recent_loaded_filename, 'new_file')
2363
- assert_nil @hd.load_auto_blocks([])
2364
- end
2365
-
2366
- def test_load_auto_blocks_without_block_name
2367
- @hd.instance_variable_set(:@delegate_object, {
2368
- document_load_opts_block_name: nil,
2369
- filename: 'new_file'
2370
- })
2371
- assert_nil @hd.load_auto_blocks([])
2372
- end
2373
- end
2374
-
2375
2392
  class TestHashDelegatorMenuChromeColoredOption < Minitest::Test
2376
2393
  def setup
2377
2394
  @hd = HashDelegator.new
@@ -2566,7 +2583,6 @@ if $PROGRAM_NAME == __FILE__
2566
2583
  end
2567
2584
  end
2568
2585
 
2569
- ####
2570
2586
  class TestHashDelegatorYieldToBlock < Minitest::Test
2571
2587
  def setup
2572
2588
  @hd = HashDelegator.new
data/lib/link_history.rb CHANGED
@@ -5,18 +5,20 @@
5
5
  module MarkdownExec
6
6
  class LinkState
7
7
  attr_accessor :block_name, :document_filename,
8
- :inherited_block_names, :inherited_lines
8
+ :inherited_block_names, :inherited_dependencies, :inherited_lines
9
9
 
10
10
  # Initialize the LinkState with keyword arguments for each attribute.
11
11
  # @param block_name [String, nil] the name of the block.
12
12
  # @param document_filename [String, nil] the filename of the document.
13
13
  # @param inherited_block_names [Array<String>, nil] the names of the inherited blocks.
14
+ # @param inherited_dependencies [?, nil] the dependecy hierarcy.
14
15
  # @param inherited_lines [Array<String>, nil] the inherited lines of code.
15
16
  def initialize(block_name: nil, document_filename: nil,
16
- inherited_block_names: [], inherited_lines: nil)
17
+ inherited_block_names: [], inherited_dependencies: nil, inherited_lines: nil)
17
18
  @block_name = block_name
18
19
  @document_filename = document_filename
19
20
  @inherited_block_names = inherited_block_names
21
+ @inherited_dependencies = inherited_dependencies
20
22
  @inherited_lines = inherited_lines
21
23
  end
22
24
 
@@ -34,6 +36,7 @@ module MarkdownExec
34
36
  other.block_name == block_name &&
35
37
  other.document_filename == document_filename &&
36
38
  other.inherited_block_names == inherited_block_names &&
39
+ other.inherited_dependencies == inherited_dependencies &&
37
40
  other.inherited_lines == inherited_lines
38
41
  end
39
42
  end
@@ -7,5 +7,5 @@ module MarkdownExec
7
7
  BIN_NAME = 'mde'
8
8
  GEM_NAME = 'markdown_exec'
9
9
  TAP_DEBUG = 'MDE_DEBUG'
10
- VERSION = '1.8.4'
10
+ VERSION = '1.8.5'
11
11
  end
data/lib/markdown_exec.rb CHANGED
@@ -49,6 +49,11 @@ def dp(str)
49
49
  lout " => #{str}", level: DISPLAY_LEVEL_DEBUG
50
50
  end
51
51
 
52
+ def rbi
53
+ pp(caller.take(4).map.with_index { |line, ind| " - #{ind}: #{line}" })
54
+ binding.irb
55
+ end
56
+
52
57
  def rbp
53
58
  rpry
54
59
  pp(caller.take(4).map.with_index { |line, ind| " - #{ind}: #{line}" })
@@ -58,7 +63,7 @@ end
58
63
  def bpp(*args)
59
64
  pp '+ bpp()'
60
65
  pp(*args.map.with_index { |line, ind| " - #{ind}: #{line}" })
61
- rbp
66
+ rbi
62
67
  end
63
68
 
64
69
  def rpry
@@ -528,6 +533,8 @@ module MarkdownExec
528
533
  execute_block_with_error_handling
529
534
  rescue StandardError
530
535
  error_handler('run')
536
+ ensure
537
+ yield if block_given?
531
538
  end
532
539
 
533
540
  private
data/lib/menu.src.yml CHANGED
@@ -92,6 +92,14 @@
92
92
  :opt_name: document_load_opts_block_name
93
93
  :procname: val_as_str
94
94
 
95
+ - :arg_name: BOOL
96
+ :default: false
97
+ :description: Dump @delegate_object
98
+ :env_var: MDE_DUMP_DELEGATE_OBJECT
99
+ :long_name: dump-dump-delegate-object
100
+ :opt_name: dump_delegate_object
101
+ :procname: val_as_bool
102
+
95
103
  - :arg_name: BOOL
96
104
  :default: false
97
105
  :description: Dump BlocksInFile (stage 1)
@@ -100,6 +108,14 @@
100
108
  :opt_name: dump_blocks_in_file
101
109
  :procname: val_as_bool
102
110
 
111
+ - :arg_name: BOOL
112
+ :default: false
113
+ :description: Dump inherited lines
114
+ :env_var: MDE_DUMP_INHERITED_LINES
115
+ :long_name: dump-dump-inherited-lines
116
+ :opt_name: dump_inherited_lines
117
+ :procname: val_as_bool
118
+
103
119
  - :arg_name: BOOL
104
120
  :default: false
105
121
  :description: Dump MenuBlocks (stage 2)
data/lib/menu.yml CHANGED
@@ -1,4 +1,4 @@
1
- # MDE - Markdown Executor (1.8.4)
1
+ # MDE - Markdown Executor (1.8.5)
2
2
  ---
3
3
  - :description: Show current configuration values
4
4
  :procname: show_config
@@ -77,6 +77,13 @@
77
77
  :env_var: MDE_DOCUMENT_LOAD_OPTS_BLOCK_NAME
78
78
  :opt_name: document_load_opts_block_name
79
79
  :procname: val_as_str
80
+ - :arg_name: BOOL
81
+ :default: false
82
+ :description: Dump @delegate_object
83
+ :env_var: MDE_DUMP_DELEGATE_OBJECT
84
+ :long_name: dump-dump-delegate-object
85
+ :opt_name: dump_delegate_object
86
+ :procname: val_as_bool
80
87
  - :arg_name: BOOL
81
88
  :default: false
82
89
  :description: Dump BlocksInFile (stage 1)
@@ -84,6 +91,13 @@
84
91
  :long_name: dump-blocks-in-file
85
92
  :opt_name: dump_blocks_in_file
86
93
  :procname: val_as_bool
94
+ - :arg_name: BOOL
95
+ :default: false
96
+ :description: Dump inherited lines
97
+ :env_var: MDE_DUMP_INHERITED_LINES
98
+ :long_name: dump-dump-inherited-lines
99
+ :opt_name: dump_inherited_lines
100
+ :procname: val_as_bool
87
101
  - :arg_name: BOOL
88
102
  :default: false
89
103
  :description: Dump MenuBlocks (stage 2)
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.8.4
4
+ version: 1.8.5
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-12-16 00:00:00.000000000 Z
11
+ date: 2023-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: clipboard
@@ -119,6 +119,7 @@ files:
119
119
  - examples/import1.md
120
120
  - examples/include.md
121
121
  - examples/infile_config.md
122
+ - examples/linked.md
122
123
  - examples/linked1.md
123
124
  - examples/linked2.md
124
125
  - examples/linked3.md