markdown_exec 1.8.4 → 1.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml 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