markdown_exec 1.8.2 → 1.8.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,134 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+ module MarkdownExec
6
+ class LinkState
7
+ attr_accessor :block_name, :document_filename,
8
+ :inherited_block_names, :inherited_dependencies, :inherited_lines
9
+
10
+ # Initialize the LinkState with keyword arguments for each attribute.
11
+ # @param block_name [String, nil] the name of the block.
12
+ # @param document_filename [String, nil] the filename of the document.
13
+ # @param inherited_block_names [Array<String>, nil] the names of the inherited blocks.
14
+ # @param inherited_dependencies [?, nil] the dependecy hierarcy.
15
+ # @param inherited_lines [Array<String>, nil] the inherited lines of code.
16
+ def initialize(block_name: nil, document_filename: nil,
17
+ inherited_block_names: [], inherited_dependencies: nil, inherited_lines: nil)
18
+ @block_name = block_name
19
+ @document_filename = document_filename
20
+ @inherited_block_names = inherited_block_names
21
+ @inherited_dependencies = inherited_dependencies
22
+ @inherited_lines = inherited_lines
23
+ end
24
+
25
+ # Creates an empty LinkState instance.
26
+ # @return [LinkState] an instance with all attributes set to their default values.
27
+ def self.empty
28
+ new
29
+ end
30
+
31
+ # Custom equality method to compare LinkState objects.
32
+ # @param other [LinkState] the other LinkState object to compare with.
33
+ # @return [Boolean] true if the objects are equal, false otherwise.
34
+ def ==(other)
35
+ other.class == self.class &&
36
+ other.block_name == block_name &&
37
+ other.document_filename == document_filename &&
38
+ other.inherited_block_names == inherited_block_names &&
39
+ other.inherited_dependencies == inherited_dependencies &&
40
+ other.inherited_lines == inherited_lines
41
+ end
42
+ end
43
+
44
+ class LinkHistory
45
+ def initialize
46
+ @history = []
47
+ end
48
+
49
+ # Peeks at the most recent LinkState, returns an empty LinkState if stack is empty.
50
+ def peek
51
+ @history.last || LinkState.empty
52
+ end
53
+
54
+ # Pops the most recent LinkState off the stack, returns an empty LinkState if stack is empty.
55
+ def pop
56
+ @history.pop || LinkState.empty
57
+ end
58
+
59
+ def prior_state_exist?
60
+ peek.document_filename.present?
61
+ end
62
+
63
+ # Pushes a LinkState onto the stack.
64
+ def push(link_state)
65
+ @history.push(link_state)
66
+ end
67
+ end
68
+ end
69
+
70
+ if $PROGRAM_NAME == __FILE__
71
+ require 'bundler/setup'
72
+ Bundler.require(:default)
73
+
74
+ require 'minitest/autorun'
75
+ require 'mocha/minitest'
76
+
77
+ module MarkdownExec
78
+ class TestLinkHistory < Minitest::Test
79
+ def setup
80
+ @link_history = LinkHistory.new
81
+ @link_state1 = LinkState.new(block_name: 'block1', document_filename: 'document1.txt',
82
+ inherited_lines: ['code1.rb'])
83
+ @link_state2 = LinkState.new(block_name: 'block2', document_filename: 'document2.txt',
84
+ inherited_lines: ['code2.rb'])
85
+ end
86
+
87
+ def test_push
88
+ @link_history.push(@link_state1)
89
+ assert_equal @link_state1, @link_history.peek
90
+ end
91
+
92
+ def test_pop
93
+ @link_history.push(@link_state1)
94
+ @link_history.push(@link_state2)
95
+ assert_equal @link_state2, @link_history.pop
96
+ assert_equal @link_state1, @link_history.peek
97
+ end
98
+
99
+ def test_peek_empty
100
+ assert_equal LinkState.empty, @link_history.peek
101
+ end
102
+
103
+ def test_pop_empty
104
+ assert_equal LinkState.empty, @link_history.pop
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ __END__
111
+
112
+ To generate the Ruby classes `LinkState` and `LinkHistory` with their current features and specifications, including the custom `==` method for object comparison and the implementation to handle empty states, you can use the following prompt:
113
+
114
+ ---
115
+
116
+ Create Ruby classes `LinkState` and `LinkHistory` with the following specifications:
117
+
118
+ 1. **Class `LinkState`**:
119
+ - Attributes: `block_name`, `document_filename`, `inherited_lines`.
120
+ - Initialize with optional parameters for each attribute, defaulting to `nil`.
121
+ - Include a class method `empty` that creates an instance with all attributes set to `nil`.
122
+ - Implement a custom `==` method for comparing instances based on attribute values.
123
+
124
+ 2. **Class `LinkHistory`**:
125
+ - Use an array to manage a stack of `LinkState` instances.
126
+ - Implement the following methods:
127
+ - `push`: Adds a `LinkState` instance to the top of the stack.
128
+ - `pop`: Removes and returns the most recent `LinkState` from the stack, or returns an empty `LinkState` if the stack is empty.
129
+ - `peek`: Returns the most recent `LinkState` without removing it from the stack, or an empty `LinkState` if the stack is empty.
130
+
131
+ 3. **Testing**:
132
+ - Write Minitest test cases to validate each method in `LinkHistory`. Test scenarios should include pushing and popping `LinkState` instances, and handling an empty `LinkHistory`.
133
+
134
+ The goal is to create a robust and efficient implementation of these classes, ensuring proper handling of stack operations and object comparisons.
@@ -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.2'
10
+ VERSION = '1.8.5'
11
11
  end
data/lib/markdown_exec.rb CHANGED
@@ -41,8 +41,6 @@ tap_config envvar: MarkdownExec::TAP_DEBUG
41
41
  $stderr.sync = true
42
42
  $stdout.sync = true
43
43
 
44
- MDE_HISTORY_ENV_NAME = 'MDE_MENU_HISTORY'
45
-
46
44
  # custom error: file specified is missing
47
45
  #
48
46
  class FileMissingError < StandardError; end
@@ -51,6 +49,11 @@ def dp(str)
51
49
  lout " => #{str}", level: DISPLAY_LEVEL_DEBUG
52
50
  end
53
51
 
52
+ def rbi
53
+ pp(caller.take(4).map.with_index { |line, ind| " - #{ind}: #{line}" })
54
+ binding.irb
55
+ end
56
+
54
57
  def rbp
55
58
  rpry
56
59
  pp(caller.take(4).map.with_index { |line, ind| " - #{ind}: #{line}" })
@@ -60,7 +63,7 @@ end
60
63
  def bpp(*args)
61
64
  pp '+ bpp()'
62
65
  pp(*args.map.with_index { |line, ind| " - #{ind}: #{line}" })
63
- rbp
66
+ rbi
64
67
  end
65
68
 
66
69
  def rpry
@@ -172,26 +175,6 @@ module MarkdownExec
172
175
  }
173
176
  end
174
177
 
175
- def clear_required_file
176
- ENV['MDE_LINK_REQUIRED_FILE'] = ''
177
- end
178
-
179
- # # Deletes a required temporary file specified by an environment variable.
180
- # # The function checks if the file exists before attempting to delete it.
181
- # # Clears the environment variable after deletion.
182
- # #
183
- # def delete_required_temp_file
184
- # temp_blocks_file_path = ENV.fetch('MDE_LINK_REQUIRED_FILE', nil)
185
-
186
- # return if temp_blocks_file_path.nil? || temp_blocks_file_path.empty?
187
-
188
- # FileUtils.rm_f(temp_blocks_file_path)
189
-
190
- # clear_required_file
191
- # rescue StandardError
192
- # error_handler('delete_required_temp_file')
193
- # end
194
-
195
178
  public
196
179
 
197
180
  ## Determines the correct filename to use for searching files
@@ -368,6 +351,16 @@ module MarkdownExec
368
351
  :menu_chrome_color)}"
369
352
  searcher = DirectorySearcher.new(value, [@options[:path]])
370
353
 
354
+ @fout.fout 'In file contents'
355
+ hash = searcher.search_in_file_contents
356
+ hash.each.with_index do |(key, v2), i1|
357
+ @fout.fout format('- %3.d: %s', i1 + 1, key)
358
+ @fout.fout AnsiFormatter.new(options).format_and_highlight_array(
359
+ v2.map { |nl| format('=%4.d: %s', nl.index, nl.line) },
360
+ highlight: [value]
361
+ )
362
+ end
363
+
371
364
  @fout.fout 'In directory names'
372
365
  @fout.fout AnsiFormatter.new(options).format_and_highlight_array(
373
366
  searcher.search_in_directory_names, highlight: [value]
@@ -378,15 +371,6 @@ module MarkdownExec
378
371
  searcher.search_in_file_names, highlight: [value]
379
372
  ).join("\n")
380
373
 
381
- @fout.fout 'In file contents'
382
- hash = searcher.search_in_file_contents
383
- hash.each.with_index do |(key, v2), i1|
384
- @fout.fout format('- %3.d: %s', i1 + 1, key)
385
- @fout.fout AnsiFormatter.new(options).format_and_highlight_array(
386
- v2.map { |nl| format('=%4.d: %s', nl.index, nl.line) },
387
- highlight: [value]
388
- )
389
- end
390
374
  exit
391
375
  }
392
376
  when 'help'
@@ -545,12 +529,12 @@ module MarkdownExec
545
529
  public
546
530
 
547
531
  def run
548
- clear_required_file
549
532
  initialize_and_parse_cli_options
550
533
  execute_block_with_error_handling
551
- @options.delete_required_temp_file
552
534
  rescue StandardError
553
535
  error_handler('run')
536
+ ensure
537
+ yield if block_given?
554
538
  end
555
539
 
556
540
  private
data/lib/mdoc.rb CHANGED
@@ -3,8 +3,8 @@
3
3
 
4
4
  # encoding=utf-8
5
5
 
6
- require_relative 'filter'
7
6
  require_relative 'block_types'
7
+ require_relative 'filter'
8
8
 
9
9
  module MarkdownExec
10
10
  ##
@@ -75,7 +75,6 @@ module MarkdownExec
75
75
  raise "Named code block `#{name}` not found. (@#{__LINE__})"
76
76
  end
77
77
 
78
- # all_dependency_names = [name_block.oname] + recursively_required(name_block[:reqs])
79
78
  dependencies = collect_dependencies(name_block[:oname])
80
79
  all_dependency_names = collect_unique_names(dependencies).push(name_block[:oname]).uniq
81
80
  unmet_dependencies = all_dependency_names.dup
@@ -91,10 +90,11 @@ module MarkdownExec
91
90
  else
92
91
  []
93
92
  end + [fcb]
94
- end.flatten(1) #.tap { rbp }
95
- { all_dependency_names: all_dependency_names,
96
- blocks: blocks,
97
- dependencies: dependencies,
93
+ end.flatten(1)
94
+
95
+ { all_dependency_names: all_dependency_names,
96
+ blocks: blocks,
97
+ dependencies: dependencies,
98
98
  unmet_dependencies: unmet_dependencies }
99
99
  end
100
100
 
@@ -103,26 +103,37 @@ module MarkdownExec
103
103
  # @param name [String] The name of the code block to start the collection from.
104
104
  # @return [Array<String>] An array of strings containing the collected code blocks.
105
105
  #
106
- def collect_recursively_required_code(name, label_body: true, label_format_above: nil, label_format_below: nil)
106
+ def collect_recursively_required_code(name, label_body: true, label_format_above: nil,
107
+ label_format_below: nil, block_source:)
107
108
  block_search = collect_recursively_required_blocks(name)
108
- block_search.merge({ code: collect_wrapped_blocks(block_search[:blocks]).map do |fcb|
109
- if fcb[:cann]
110
- collect_block_code_cann(fcb)
111
- elsif fcb[:stdout]
112
- collect_block_code_stdout(fcb)
113
- elsif [BlockType::LINK, BlockType::OPTS,
114
- BlockType::VARS].include? fcb[:shell]
115
- nil
116
- elsif fcb[:shell] == BlockType::PORT
117
- collect_block_code_shell(fcb)
118
- elsif label_body
119
- [label_format_above && format(label_format_above, { name: fcb[:oname] })] +
120
- fcb[:body] +
121
- [label_format_below && format(label_format_below, { name: fcb[:oname] })]
122
- else # raw body
123
- fcb[:body]
124
- end
125
- end.compact.flatten(1).compact })
109
+ if block_search[:blocks]
110
+ blocks = collect_wrapped_blocks(block_search[:blocks])
111
+ block_search.merge(
112
+ { block_names: blocks.map { |block| block[:oname] },
113
+ code: blocks.map do |fcb|
114
+ if fcb[:cann]
115
+ collect_block_code_cann(fcb)
116
+ elsif fcb[:stdout]
117
+ collect_block_code_stdout(fcb)
118
+ elsif [BlockType::LINK, BlockType::OPTS,
119
+ BlockType::VARS].include? fcb[:shell]
120
+ nil
121
+ elsif fcb[:shell] == BlockType::PORT
122
+ collect_block_code_shell(fcb)
123
+ elsif label_body
124
+ [label_format_above && format(label_format_above,
125
+ block_source.merge({ block_name: fcb[:oname] }))] +
126
+ fcb[:body] +
127
+ [label_format_below && format(label_format_below,
128
+ block_source.merge({ block_name: fcb[:oname] }))]
129
+ else # raw body
130
+ fcb[:body]
131
+ end
132
+ end.compact.flatten(1).compact }
133
+ )
134
+ else
135
+ block_search.merge({ block_names: [], code: [] })
136
+ end
126
137
  end
127
138
 
128
139
  def collect_unique_names(hash)
@@ -279,11 +290,10 @@ module MarkdownExec
279
290
  return memo unless source
280
291
 
281
292
  if (block = get_block_by_anyname(source)).nil? || block.keys.empty?
282
- if true
283
- return memo
284
- else
285
- raise "Named code block `#{source}` not found. (@#{__LINE__})"
286
- end
293
+ return memo if true
294
+
295
+ raise "Named code block `#{source}` not found. (@#{__LINE__})"
296
+
287
297
  end
288
298
 
289
299
  return memo unless block[:reqs]
data/lib/menu.src.yml CHANGED
@@ -92,17 +92,35 @@
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)
98
106
  :env_var: MDE_DUMP_BLOCKS_IN_FILE
107
+ :long_name: dump-blocks-in-file
99
108
  :opt_name: dump_blocks_in_file
100
109
  :procname: val_as_bool
101
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
+
102
119
  - :arg_name: BOOL
103
120
  :default: false
104
121
  :description: Dump MenuBlocks (stage 2)
105
122
  :env_var: MDE_DUMP_MENU_BLOCKS
123
+ :long_name: dump-menu-blocks
106
124
  :opt_name: dump_menu_blocks
107
125
  :procname: val_as_bool
108
126
 
@@ -110,6 +128,7 @@
110
128
  :default: false
111
129
  :description: Dump selected block
112
130
  :env_var: MDE_DUMP_SELECTED_BLOCK
131
+ :long_name: dump-selected-block
113
132
  :opt_name: dump_selected_block
114
133
  :procname: val_as_bool
115
134
 
@@ -846,13 +865,13 @@
846
865
  :opt_name: shell
847
866
  :procname: val_as_str
848
867
 
849
- - :default: "# -^- +%{name} -^-"
868
+ - :default: "# -^- +%{block_name} -o- %{document_filename} -^-"
850
869
  :description: shell_code_label_format_above
851
870
  :env_var: MDE_SHELL_CODE_LABEL_FORMAT_ABOVE
852
871
  :opt_name: shell_code_label_format_above
853
872
  :procname: val_as_str
854
873
 
855
- - :default: "# -v- +%{name} -v-"
874
+ - :default: "# -v- +%{block_name} -v-"
856
875
  :description: shell_code_label_format_below
857
876
  :env_var: MDE_SHELL_CODE_LABEL_FORMAT_BELOW
858
877
  :opt_name: shell_code_label_format_below
data/lib/menu.yml CHANGED
@@ -1,4 +1,4 @@
1
- # MDE - Markdown Executor (1.8.2)
1
+ # MDE - Markdown Executor (1.8.5)
2
2
  ---
3
3
  - :description: Show current configuration values
4
4
  :procname: show_config
@@ -77,22 +77,39 @@
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)
83
90
  :env_var: MDE_DUMP_BLOCKS_IN_FILE
91
+ :long_name: dump-blocks-in-file
84
92
  :opt_name: dump_blocks_in_file
85
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
86
101
  - :arg_name: BOOL
87
102
  :default: false
88
103
  :description: Dump MenuBlocks (stage 2)
89
104
  :env_var: MDE_DUMP_MENU_BLOCKS
105
+ :long_name: dump-menu-blocks
90
106
  :opt_name: dump_menu_blocks
91
107
  :procname: val_as_bool
92
108
  - :arg_name: BOOL
93
109
  :default: false
94
110
  :description: Dump selected block
95
111
  :env_var: MDE_DUMP_SELECTED_BLOCK
112
+ :long_name: dump-selected-block
96
113
  :opt_name: dump_selected_block
97
114
  :procname: val_as_bool
98
115
  - :default: fg_rgbh_ff_00_7f
@@ -727,12 +744,12 @@
727
744
  :env_var: MDE_SHELL
728
745
  :opt_name: shell
729
746
  :procname: val_as_str
730
- - :default: "# -^- +%{name} -^-"
747
+ - :default: "# -^- +%{block_name} -o- %{document_filename} -^-"
731
748
  :description: shell_code_label_format_above
732
749
  :env_var: MDE_SHELL_CODE_LABEL_FORMAT_ABOVE
733
750
  :opt_name: shell_code_label_format_above
734
751
  :procname: val_as_str
735
- - :default: "# -v- +%{name} -v-"
752
+ - :default: "# -v- +%{block_name} -v-"
736
753
  :description: shell_code_label_format_below
737
754
  :env_var: MDE_SHELL_CODE_LABEL_FORMAT_BELOW
738
755
  :opt_name: shell_code_label_format_below
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.2
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-12 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
@@ -145,6 +146,7 @@ files:
145
146
  - lib/fout.rb
146
147
  - lib/hash.rb
147
148
  - lib/hash_delegator.rb
149
+ - lib/link_history.rb
148
150
  - lib/markdown_exec.rb
149
151
  - lib/markdown_exec/version.rb
150
152
  - lib/mdoc.rb