markdown_exec 2.2.0 → 2.4.0

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.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +16 -4
  3. data/CHANGELOG.md +28 -0
  4. data/Gemfile.lock +1 -1
  5. data/Rakefile +32 -8
  6. data/bats/bats.bats +33 -0
  7. data/bats/block-types.bats +56 -0
  8. data/bats/cli.bats +74 -0
  9. data/bats/fail.bats +11 -0
  10. data/bats/history.bats +34 -0
  11. data/bats/markup.bats +66 -0
  12. data/bats/mde.bats +29 -0
  13. data/bats/options.bats +92 -0
  14. data/bats/test_helper.bash +152 -0
  15. data/bin/tab_completion.sh +44 -20
  16. data/docs/dev/block-type-opts.md +10 -0
  17. data/docs/dev/block-type-port.md +24 -0
  18. data/docs/dev/block-type-vars.md +7 -0
  19. data/docs/dev/pass-through-arguments.md +8 -0
  20. data/docs/dev/specs-import.md +9 -0
  21. data/docs/dev/specs.md +83 -0
  22. data/docs/dev/text-decoration.md +7 -0
  23. data/examples/bash-blocks.md +4 -4
  24. data/examples/block-names.md +40 -5
  25. data/examples/import0.md +23 -0
  26. data/examples/import1.md +13 -0
  27. data/examples/link-blocks-vars.md +3 -3
  28. data/examples/opts-blocks-require.md +6 -6
  29. data/examples/table-markup.md +31 -0
  30. data/examples/text-markup.md +58 -0
  31. data/examples/vars-blocks.md +2 -2
  32. data/examples/wrap.md +87 -9
  33. data/lib/ansi_formatter.rb +12 -6
  34. data/lib/ansi_string.rb +153 -0
  35. data/lib/argument_processor.rb +160 -0
  36. data/lib/cached_nested_file_reader.rb +4 -2
  37. data/lib/ce_get_cost_and_usage.rb +4 -3
  38. data/lib/cli.rb +1 -1
  39. data/lib/colorize.rb +41 -0
  40. data/lib/constants.rb +17 -0
  41. data/lib/directory_searcher.rb +4 -2
  42. data/lib/doh.rb +190 -0
  43. data/lib/env.rb +1 -1
  44. data/lib/exceptions.rb +9 -6
  45. data/lib/fcb.rb +0 -199
  46. data/lib/filter.rb +18 -5
  47. data/lib/find_files.rb +8 -3
  48. data/lib/format_table.rb +406 -0
  49. data/lib/hash_delegator.rb +939 -611
  50. data/lib/hierarchy_string.rb +221 -0
  51. data/lib/input_sequencer.rb +19 -11
  52. data/lib/instance_method_wrapper.rb +2 -1
  53. data/lib/layered_hash.rb +143 -0
  54. data/lib/link_history.rb +22 -8
  55. data/lib/markdown_exec/version.rb +1 -1
  56. data/lib/markdown_exec.rb +420 -165
  57. data/lib/mdoc.rb +38 -38
  58. data/lib/menu.src.yml +832 -680
  59. data/lib/menu.yml +814 -689
  60. data/lib/namer.rb +6 -12
  61. data/lib/object_present.rb +1 -1
  62. data/lib/option_value.rb +7 -3
  63. data/lib/poly.rb +33 -14
  64. data/lib/resize_terminal.rb +60 -52
  65. data/lib/saved_assets.rb +45 -34
  66. data/lib/saved_files_matcher.rb +6 -3
  67. data/lib/streams_out.rb +7 -1
  68. data/lib/table_extractor.rb +166 -0
  69. data/lib/tap.rb +5 -6
  70. data/lib/text_analyzer.rb +236 -0
  71. metadata +28 -3
  72. data/lib/std_out_err_logger.rb +0 -119
data/lib/colorize.rb CHANGED
@@ -13,15 +13,25 @@ class String
13
13
  # @return [String] The formatted string.
14
14
  def method_missing(method_name, *args, &block)
15
15
  case method_name.to_s
16
+ # when /^bg_rgb_/
17
+ # bytes = $'.split('_')
18
+ # bg_rgb_color(bytes[0..2].join(';'))
16
19
  when /^fg_bg_rgb_/
20
+ pp [__LINE__, caller[0]]; binding.irb
17
21
  bytes = $'.split('_')
18
22
  fg_bg_rgb_color(bytes[0..2].join(';'), bytes[3..5].join(';'))
19
23
  when /^fg_bg_rgbh_/
24
+ pp [__LINE__, caller[0]]; binding.irb
20
25
  hex_to_fg_bg_rgb($')
21
26
  when /^fg_rgb_/
27
+ pp [__LINE__, caller[0]]; binding.irb
22
28
  fg_rgb_color($'.gsub('_', ';'))
23
29
  when /^fg_rgbh_/
30
+ pp [__LINE__, caller[0]]; binding.irb
24
31
  hex_to_rgb($')
32
+
33
+ when 'to_a', 'to_ary', 'to_hash', 'to_int', 'to_io', 'to_regexp'
34
+ nil
25
35
  else
26
36
  super
27
37
  end
@@ -31,14 +41,24 @@ class String
31
41
  #
32
42
  # @return [String] The string wrapped in an ANSI control sequence.
33
43
  def ansi_control_sequence
44
+ pp [__LINE__, caller[0]]; binding.irb
34
45
  "\033[#{self}\033[0m"
35
46
  end
36
47
 
48
+ # # Applies a 24-bit RGB background color to the string.
49
+ # #
50
+ # # @param rgb [String] The RGB color, expressed as a string like "1;2;3".
51
+ # # @return [String] The string with the applied RGB foreground color.
52
+ # def bg_rgb_color(rgb)
53
+ # "48;2;#{rgb}m#{self}".ansi_control_sequence
54
+ # end
55
+
37
56
  # Applies a 24-bit RGB foreground color to the string.
38
57
  #
39
58
  # @param rgb [String] The RGB color, expressed as a string like "1;2;3".
40
59
  # @return [String] The string with the applied RGB foreground color.
41
60
  def fg_bg_rgb_color(fg_rgb, bg_rgb)
61
+ pp [__LINE__, caller[0]]; binding.irb
42
62
  "38;2;#{fg_rgb}m\033[48;2;#{bg_rgb}m#{self}".ansi_control_sequence
43
63
  end
44
64
 
@@ -47,6 +67,7 @@ class String
47
67
  # @param rgb [String] The RGB color, expressed as a string like "1;2;3".
48
68
  # @return [String] The string with the applied RGB foreground color.
49
69
  def fg_rgb_color(rgb)
70
+ pp [__LINE__, caller[0]]; binding.irb
50
71
  "38;2;#{rgb}m#{self}".ansi_control_sequence
51
72
  end
52
73
 
@@ -55,6 +76,7 @@ class String
55
76
  # @param hex_str [String] The RGB color, expressed as a hex string like "FF00FF".
56
77
  # @return [String] The string with the applied RGB foreground color.
57
78
  def hex_to_fg_bg_rgb(hex_str)
79
+ pp [__LINE__, caller[0]]; binding.irb
58
80
  values = hex_str.split('_').map { |hex| hex.to_i(16).to_s }
59
81
  fg_bg_rgb_color(
60
82
  values[0..2].join(';'),
@@ -67,6 +89,7 @@ class String
67
89
  # @param hex_str [String] The RGB color, expressed as a hex string like "FF00FF".
68
90
  # @return [String] The string with the applied RGB foreground color.
69
91
  def hex_to_rgb(hex_str)
92
+ pp [__LINE__, caller[0]]; binding.irb
70
93
  fg_rgb_color(
71
94
  hex_str.split('_').map { |hex| hex.to_i(16).to_s }.join(';')
72
95
  )
@@ -76,6 +99,7 @@ class String
76
99
  #
77
100
  # @return [String] The original string.
78
101
  def plain
102
+ pp [__LINE__, caller[0]]; binding.irb
79
103
  self
80
104
  end
81
105
 
@@ -101,4 +125,21 @@ class String
101
125
  def red; fg_rgbh_FF_00_00; end
102
126
  def violet; fg_rgbh_94_00_D3; end
103
127
  def yellow; fg_rgbh_FF_FF_00; end
128
+
129
+ def x
130
+ pp [__LINE__, caller[1]]; binding.irb
131
+ end
132
+
133
+ # graphics modes
134
+ def bold; x; "\033[1m#{self}\033[22m"; end
135
+ def bold_italic; x; "\033[1m\033[3m#{self}\033[22m\033[23m"; end
136
+ def bold_underline; x; "\033[1m\033[4m#{self}\033[22m\033[24m"; end
137
+ def dim; x; "\033[2m#{self}\033[22m"; end
138
+ def italic; x; "\033[3m#{self}\033[23m"; end
139
+ def underline; x; "\033[4m#{self}\033[24m"; end
140
+ def underline_italic; x; "\033[4m\033[3m#{self}\033[23m\033[24m"; end
141
+ def blinking; x; "\033[5m#{self}\033[25m"; end
142
+ def inverse; x; "\033[7m#{self}\033[27m"; end
143
+ def hidden; x; "\033[8m#{self}\033[28m"; end
144
+ def strikethrough; x; "\033[9m#{self}\033[29m"; end
104
145
  end
data/lib/constants.rb CHANGED
@@ -5,6 +5,22 @@
5
5
 
6
6
  require_relative 'block_types'
7
7
 
8
+ class AppInterrupt < StandardError; end
9
+ class BlockMissing < StandardError; end
10
+
11
+ class ArgPro
12
+ ActFileIsMissing = :file_missing
13
+ ActFind = :find
14
+ ActSetBlockName = :block_name
15
+ ActSetFileName = :set_filename
16
+ ActSetOption = :set_option
17
+ ActSetPath = :set_path
18
+ ArgIsOption = :option
19
+ ArgIsPosition = :position
20
+ CallProcess = :proc_name
21
+ ConvertValue = :convert
22
+ end
23
+
8
24
  class ExecutionStreams
9
25
  STD_ERR = :stderr
10
26
  STD_IN = :stdin
@@ -30,6 +46,7 @@ class LinkKeys
30
46
  end
31
47
 
32
48
  class LoadFile
49
+ EXIT = :exit
33
50
  LOAD = true
34
51
  REUSE = false
35
52
  end
@@ -155,11 +155,13 @@ class DirectorySearcher
155
155
  Find.prune unless @include_subdirectories || path == p
156
156
  next unless File.file?(p)
157
157
 
158
- next if @filename_glob && !File.fnmatch(@filename_glob, File.basename(p))
158
+ next if @filename_glob && !File.fnmatch(@filename_glob,
159
+ File.basename(p))
159
160
 
160
161
  begin
161
162
  File.foreach(p).with_index(1) do |line, line_num| # Index starts from 1 for line numbers
162
- line_utf8 = line.encode('UTF-8', invalid: :replace, undef: :replace, replace: '')
163
+ line_utf8 = line.encode('UTF-8', invalid: :replace,
164
+ undef: :replace, replace: '')
163
165
 
164
166
  line_utf8 = yield(line_utf8) if block_given?
165
167
 
data/lib/doh.rb ADDED
@@ -0,0 +1,190 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # encoding=utf-8
5
+
6
+ class DOH < Hash
7
+ # Initialize with an optional hash and a block
8
+ def initialize(initial_hash = {}, &block)
9
+ super() # Initialize the parent Hash
10
+ self.merge!(initial_hash) # Merge the initial hash into the current hash
11
+ self.default_proc = block if block_given?
12
+ end
13
+
14
+ # Override method_missing to pass undefined methods to the parent Hash
15
+ def method_missing(method_name, *args, &block)
16
+ # sc = caller[0].split; pp ['DOH.mm',method_name,sc[-1],sc[-2].split('/')[-1].split(':')[0..1].join(':')]
17
+ if Hash.instance_methods.include?(method_name)
18
+ super
19
+ else
20
+ raise NoMethodError, "undefined method `#{method_name}` for #{self}:#{self.class}"
21
+ end
22
+ end
23
+
24
+ # Ensure respond_to_missing? is correctly implemented
25
+ def respond_to_missing?(method_name, include_private = false)
26
+ # sc = caller[0].split; pp ['DOH.rtm?',method_name,sc[-1],sc[-2].split('/')[-1].split(':')[0..1].join(':')]
27
+ Hash.instance_methods.include?(method_name) || super
28
+ end
29
+ end
30
+
31
+ # class DOH < Hash
32
+ # # Initialize with an optional hash and a block
33
+ # def initialize(initial_hash = {}, &block)
34
+ # super() # Initialize the parent Hash
35
+ # self.merge!(initial_hash) # Merge the initial hash into the current hash
36
+ # self.default_proc = block if block_given?
37
+ # end
38
+
39
+ # # Override method_missing to pass undefined methods to the parent Hash
40
+ # def method_missing(method_name, *args, &block)
41
+ # # pp ['DOH.mm',method_name]
42
+ # if self.respond_to?(method_name)
43
+ # self.send(method_name, *args, &block)
44
+ # else
45
+ # super
46
+ # end
47
+ # end
48
+
49
+ # # Ensure respond_to_missing? is correctly implemented
50
+ # # pp ['DOH.rtm?',method_name]
51
+
52
+ # def respond_to_missing?(method_name, include_private = false)
53
+ # self.respond_to?(method_name) || super
54
+ # end
55
+ # end
56
+
57
+ # class LayeredHash
58
+ # def initialize(table = {}, layers: %i[main])
59
+ # @layers = layers.map { |layer| [layer, {}] }.to_h
60
+ # @current_layer = layers.first
61
+ # @layers[@current_layer] = table
62
+ # end
63
+
64
+ # private
65
+
66
+ # def method_missing(method, *args, &block)
67
+ # method_name = method.to_s
68
+ # if @layers.respond_to?(method_name)
69
+ # @layers.send(method_name, *args, &block)
70
+ # elsif method_name[-1] == '='
71
+ # @layers[method_name.chop.to_sym] = args[0]
72
+ # elsif @layers.respond_to?(method_name)
73
+ # @layers.send(method_name, *args)
74
+ # else
75
+ # @layers[method_name.to_sym]
76
+ # end
77
+ # rescue StandardError => err
78
+ # warn("ERROR ** LayeredHash.method_missing(method: #{method_name}," \
79
+ # " *args: #{args.inspect}, &block)")
80
+ # warn err.inspect
81
+ # warn(caller[0..4])
82
+ # raise err
83
+ # end
84
+
85
+ # public
86
+
87
+ # # Retrieves the value of a key from the current layer using hash notation
88
+ # def [](key)
89
+ # raise "Current layer not set" unless @current_layer
90
+
91
+ # get_from_layer(@current_layer, key)
92
+ # end
93
+
94
+ # # Sets a key-value pair in the current layer using hash notation
95
+ # def []=(key, value)
96
+ # raise "Current layer not set" unless @current_layer
97
+
98
+ # set(@current_layer, key, value)
99
+ # end
100
+
101
+ # def fetch(key, *args)
102
+ # key_sym = key.to_sym
103
+ # if respond_to?("get_#{key}")
104
+ # send("get_#{key}")
105
+ # # elsif @table.key?(key_sym)
106
+ # elsif @layers[@current_layer].key?(key_sym)
107
+ # # @table[key_sym]
108
+ # @layers[@current_layer][key_sym]
109
+ # elsif block_given?
110
+ # yield key_sym
111
+ # elsif args.count.positive?
112
+ # # binding.irb
113
+ # args.first
114
+ # else
115
+ # binding.irb
116
+ # raise KeyError, "key not found: #{key}"
117
+ # end.tap{|ret| pp([__LINE__,"Poly.fetch #{key} #{args}",'->',ret]) if $pd }
118
+ # end
119
+
120
+ # # Retrieves the value of a key from the highest priority layer that has a value
121
+ # def get(key)
122
+ # @layers.reverse_each do |_, hash|
123
+ # return hash[key] if hash.key?(key)
124
+ # end
125
+ # nil
126
+ # end
127
+
128
+ # # Retrieves the value of a key from the specified layer
129
+ # def get_from_layer(layer, key)
130
+ # if @layers.key?(layer)
131
+ # @layers[layer][key]
132
+ # else
133
+ # raise ArgumentError, "Layer #{layer} does not exist"
134
+ # end
135
+ # end
136
+
137
+ # def merge(*args)
138
+ # @layers.merge(*args).tap{|ret| pp([__LINE__,"LayeredHash.merge",'->',ret]) if $pd }
139
+ # end
140
+
141
+ # def respond_to_missing?(method_name, include_private = false)
142
+ # @layers.key?(method_name.to_sym) || super
143
+ # end
144
+
145
+ # # Sets a key-value pair in the specified layer
146
+ # def set(layer, key, value)
147
+ # if @layers.key?(layer)
148
+ # @layers[layer][key] = value
149
+ # else
150
+ # raise ArgumentError, "Layer #{layer} does not exist"
151
+ # end
152
+ # end
153
+
154
+ # # Sets the current layer for use with hash notation ([])
155
+ # def set_current_layer(layer)
156
+ # if @layers.key?(layer)
157
+ # @current_layer = layer
158
+ # else
159
+ # raise ArgumentError, "Layer #{layer} does not exist"
160
+ # end
161
+ # end
162
+
163
+ # def to_h
164
+ # @layers.to_h
165
+ # end
166
+ # end
167
+
168
+ return if $PROGRAM_NAME != __FILE__
169
+
170
+ # layered_hash = LayeredHash.new(layers: %i[low high])
171
+
172
+ # # Set current layer
173
+ # layered_hash.set_current_layer(:low)
174
+
175
+ # # Set values in the current layer using hash notation
176
+ # layered_hash[:key1] = 'low_value'
177
+ # layered_hash[:key2] = 'low_only_value'
178
+
179
+ # # Switch current layer
180
+ # layered_hash.set_current_layer(:high)
181
+
182
+ # # Set values in the new current layer using hash notation
183
+ # layered_hash[:key1] = 'high_value'
184
+
185
+ # # Get value from the specific current layer using hash notation
186
+ # puts layered_hash[:key1] # Output: 'high_value'
187
+
188
+ # # Get value from the highest priority layer
189
+ # puts layered_hash.get(:key1) # Output: 'high_value'
190
+ # puts layered_hash.get(:key2) # Output: 'low_only_value'
data/lib/env.rb CHANGED
@@ -18,7 +18,7 @@ module Env
18
18
 
19
19
  # :reek:UtilityFunction
20
20
  def env_bool_false(name)
21
- !(val = (name && ENV.fetch(name, nil))).nil? && !(val.empty? || val == '0')
21
+ !(val = name && ENV.fetch(name, nil)).nil? && !(val.empty? || val == '0')
22
22
  end
23
23
 
24
24
  # skip :reek:DataClump
data/lib/exceptions.rb CHANGED
@@ -3,10 +3,13 @@
3
3
 
4
4
  # encoding=utf-8
5
5
 
6
+ require_relative 'ansi_string'
7
+
6
8
  module Exceptions
7
9
  def self.error_handler(name = '', opts = {}, backtrace: $@, format_string: "\nError: %{name} -- %{message}", color_symbol: :red, take_count: 16)
8
- warn(error = format(format_string,
9
- { name: name, message: $! }).send(color_symbol))
10
+ warn(error = AnsiString.new(format(format_string,
11
+ { name: name,
12
+ message: $! })).send(color_symbol))
10
13
  if backtrace
11
14
  warn(backtrace.select do |s|
12
15
  s.include? 'markdown_exec'
@@ -21,10 +24,10 @@ module Exceptions
21
24
 
22
25
  def self.warn_format(message = '', opts = {})
23
26
  warn(
24
- error = format(
25
- opts.fetch(:format_string, "\nError: %{error}"),
26
- { error: message }
27
- ).send(opts.fetch(:color_symbol, :yellow))
27
+ error = AnsiString.new(format(
28
+ opts.fetch(:format_string, "\nError: %{error}"),
29
+ { error: message }
30
+ )).send(opts.fetch(:color_symbol, :yellow))
28
31
  )
29
32
  # warn(caller.take(4).map.with_index { |line, ind| " * #{ind}: #{line}" })
30
33
 
data/lib/fcb.rb CHANGED
@@ -4,7 +4,6 @@
4
4
  # encoding=utf-8
5
5
  require 'digest'
6
6
  require_relative 'namer'
7
- # require_relative 'poly'
8
7
 
9
8
  module MarkdownExec
10
9
  class Error < StandardError; end
@@ -159,201 +158,3 @@ if $PROGRAM_NAME == __FILE__
159
158
  # end
160
159
  end
161
160
  end
162
-
163
- # #!/usr/bin/env ruby
164
- # # frozen_string_literal: true
165
-
166
- # # encoding=utf-8
167
- # require 'digest'
168
- # require_relative 'poly'
169
-
170
- # # require 'ostruct'
171
-
172
- # module MarkdownExec
173
- # class Error < StandardError; end
174
-
175
- # # Fenced Code Block (FCB)
176
- # #
177
- # # This class represents a fenced code block in a markdown document.
178
- # # It allows for setting and getting attributes related to the code block,
179
- # # such as body, call, headings, and more.
180
- # #
181
- # class FCB
182
- # def initialize(options = {})
183
- # # @attrs = ({
184
- # @attrs = Poly.new({
185
- # body: nil,
186
- # call: nil,
187
- # headings: [],
188
- # dname: nil,
189
- # indent: '',
190
- # name: nil,
191
- # nickname: nil,
192
- # oname: nil,
193
- # reqs: [],
194
- # shell: '',
195
- # title: '',
196
- # random: Random.new.rand,
197
- # text: nil # displayable in menu
198
- # }.merge(options))
199
- # end
200
-
201
- # def is?(name)
202
- # (save_name == name).tap{|ret|pp [__LINE__,"is?(#{name})",'->',ret]}
203
- # end
204
-
205
- # # fenced_name: text from code
206
- # # save_name: for file system
207
- # # logical_name: used for requires, not displayed
208
- # # menu_name: displayed in menu
209
-
210
- # # used for requires, not displayed
211
- # def logical_name
212
- # (@attrs.fetch(:nickname, nil) || @attrs.fetch(:oname, nil)).tap{|ret|pp [__LINE__,"logical_name()",'->',ret]}
213
- # end
214
-
215
- # # displayed in menu
216
- # def menu_name # displayed in menu
217
- # @attrs.fetch(:nickname, nil).tap{|ret|pp [__LINE__,"menu_name()",'->',ret]}
218
- # end
219
-
220
- # # for file system
221
- # # block name in commands and documents
222
- # def save_name(id_len: 4, max_len: 48)
223
- # full = @attrs.fetch(:nickname, nil) || @attrs.fetch(:oname, nil)
224
- # trimmed = if full && full[max_len]
225
- # r = rand((10**(id_len - 1) + 1)..10**id_len).to_s
226
- # dig = Digest::MD5.hexdigest(full)[0, id_len]
227
- # full[0..max_len - id_len] + dig
228
- # else
229
- # full
230
- # end
231
-
232
- # trimmed&.to_blockname.tap{|ret|pp [__LINE__,"save_name()",'->',ret]}
233
- # end
234
-
235
- # def title=(value)
236
- # @attrs[:title] = value
237
- # end
238
-
239
- # # Derives a title from the body of an FCB object.
240
- # # @param fcb [Object] The FCB object whose title is to be derived.
241
- # # @return [String] The derived title.
242
- # def derive_title_from_body
243
- # unless (body_content = @attrs[:body])
244
- # # empty body -> empty title
245
- # @attrs[:title] = ''
246
- # return
247
- # end
248
-
249
- # # body -> title
250
- # @attrs[:title] = if body_content.count == 1
251
- # body_content.first
252
- # else
253
- # format_multiline_body_as_title(body_content)
254
- # end
255
- # end
256
-
257
- # private
258
-
259
- # # Formats multiline body content as a title string.
260
- # # indents all but first line with two spaces so it displays correctly in menu
261
- # # @param body_lines [Array<String>] The lines of body content.
262
- # # @return [String] Formatted title.
263
- # def format_multiline_body_as_title(body_lines)
264
- # body_lines.map.with_index do |line, index|
265
- # index.zero? ? line : " #{line}"
266
- # end.join("\n") << "\n"
267
- # end
268
-
269
- # # :reek:ManualDispatch
270
- # def method_missing(method, *args, &block)
271
- # method_name = method.to_s
272
- # if @attrs.respond_to?(method_name)
273
- # @attrs.send(method_name, *args, &block)
274
- # elsif method_name[-1] == '='
275
- # @attrs[method_name.chop.to_sym] = args[0]
276
- # else
277
- # @attrs[method_name.to_sym]
278
- # end
279
- # rescue StandardError => err
280
- # warn("ERROR ** FCB.method_missing(method: #{method_name}," \
281
- # " *args: #{args.inspect}, &block)")
282
- # warn err.inspect
283
- # warn(caller[0..4])
284
- # # raise StandardError, error
285
- # raise err # Here, we simply propagate the original error instead of wrapping it in a StandardError.
286
- # end
287
-
288
- # public
289
-
290
- # def respond_to_missing?(method_name, include_private = false)
291
- # @attrs.key?(method_name.to_sym) || super
292
- # end
293
-
294
- # def to_h
295
- # @attrs.to_h
296
- # end
297
-
298
- # def to_yaml
299
- # @attrs.to_yaml
300
- # end
301
- # end
302
- # end
303
-
304
- # if $PROGRAM_NAME == __FILE__
305
- # require 'bundler/setup'
306
- # Bundler.require(:default)
307
-
308
- # require 'minitest/autorun'
309
- # require 'yaml'
310
-
311
- # class FCBTest < Minitest::Test
312
- # def setup
313
- # @fcb_data = {
314
- # body: 'Sample body',
315
- # call: 'Sample call',
316
- # headings: %w[Header1 Header2],
317
- # dname: 'Sample name',
318
- # indent: '',
319
- # nickname: nil,
320
- # name: 'Sample name',
321
- # oname: 'Sample name',
322
- # reqs: %w[req1 req2],
323
- # shell: 'bash',
324
- # text: 'Sample Text',
325
- # title: 'Sample Title'
326
- # }
327
- # @fcb = MarkdownExec::FCB.new(@fcb_data)
328
- # end
329
-
330
- # def test_initialization_with_correct_data
331
- # assert_equal 'Sample body', @fcb.body
332
- # assert_equal %w[Header1 Header2], @fcb.headings
333
- # end
334
-
335
- # def test_to_h_method
336
- # assert_equal @fcb_data.merge({ random: @fcb.random }), @fcb.to_h
337
- # end
338
-
339
- # def test_to_yaml_method
340
- # assert_equal YAML.load(@fcb_data.merge({ random: @fcb.random }).to_yaml),
341
- # YAML.load(@fcb.to_yaml)
342
- # end
343
-
344
- # def test_method_missing_getter
345
- # assert_equal 'Sample Title', @fcb.title
346
- # end
347
-
348
- # def test_method_missing_setter
349
- # @fcb.title = 'New Title'
350
- # assert_equal 'New Title', @fcb.title
351
- # end
352
-
353
- # # 2023-10-09 does not trigger error; treats as option name
354
- # #
355
- # # def test_method_missing_with_unknown_method
356
- # # assert_raises(NoMethodError) { @fcb.unknown_method }
357
- # # end
358
- # end
359
- # end
data/lib/filter.rb CHANGED
@@ -3,6 +3,17 @@
3
3
 
4
4
  # encoding=utf-8
5
5
 
6
+ # Determines if a given block type is selected based on a list.
7
+ #
8
+ # @param selected_types [Array<String>, nil] An array of block types to
9
+ # check against. If nil, all types are considered selected.
10
+ # @param type [String] The block type to check for selection.
11
+ # @return [Boolean] Returns true if the type is selected or if
12
+ # selected_types is nil (indicating all types are selected).
13
+ def block_type_selected?(selected_types, type)
14
+ !selected_types || selected_types.include?(type)
15
+ end
16
+
6
17
  module MarkdownExec
7
18
  # Filter
8
19
  #
@@ -96,7 +107,8 @@ module MarkdownExec
96
107
 
97
108
  return unless shell.present? && options[:exclude_by_shell_regex].present?
98
109
 
99
- filters[:shell_exclude] = !!(shell =~ /#{options[:exclude_by_shell_regex]}/)
110
+ filters[:shell_exclude] =
111
+ !!(shell =~ /#{options[:exclude_by_shell_regex]}/)
100
112
  end
101
113
 
102
114
  # Applies additional filters to determine whether to include or
@@ -176,14 +188,15 @@ module MarkdownExec
176
188
  end
177
189
 
178
190
  # Yields to the provided block with specified parameters if certain conditions are met.
179
- # The method checks if a block is given, if the selected_messages include :blocks,
191
+ # The method checks if a block is given, if the selected_types include :blocks,
180
192
  # and if the fcb_select? method returns true for the given fcb.
181
193
  #
182
194
  # @param fcb [Object] The object to be evaluated and potentially passed to the block.
183
- # @param selected_messages [Array<Symbol>] A collection of message types, one of which must be :blocks.
195
+ # @param selected_types [Array<Symbol>] A collection of message types, one of which must be :blocks.
184
196
  # @param block [Block] A block to be called if conditions are met.
185
- def self.yield_to_block_if_applicable(fcb, selected_messages, configuration = {}, &block)
186
- if block_given? && selected_messages.include?(:blocks) &&
197
+ def self.yield_to_block_if_applicable(fcb, selected_types, configuration = {}, &block)
198
+ if block_given? &&
199
+ block_type_selected?(selected_types, :blocks) &&
187
200
  fcb_select?(configuration, fcb)
188
201
  block.call :blocks, fcb
189
202
  end
data/lib/find_files.rb CHANGED
@@ -28,7 +28,8 @@
28
28
  # Example:
29
29
  # find_files('version.rb', ['lib/**', 'spec'], true, true)
30
30
  # # This might return file paths like ['markdown_exec/version.rb', 'spec/version_spec.rb'].
31
- def find_files(pattern, paths = ['', Dir.pwd], base_dir: Dir.pwd, exclude_dirs: false, use_relative_paths: true)
31
+ def find_files(pattern, paths = ['', Dir.pwd], base_dir: Dir.pwd,
32
+ exclude_dirs: false, use_relative_paths: true)
32
33
  matched_files = []
33
34
 
34
35
  paths.each do |path_with_wildcard|
@@ -39,10 +40,14 @@ def find_files(pattern, paths = ['', Dir.pwd], base_dir: Dir.pwd, exclude_dirs:
39
40
  files = Dir.glob(search_pattern, File::FNM_DOTMATCH)
40
41
 
41
42
  # Optionally exclude "." and ".." and directory names
42
- files.reject! { |file| file.end_with?('/.', '/..') || File.directory?(file) } if exclude_dirs
43
+ files.reject! { |file|
44
+ file.end_with?('/.', '/..') || File.directory?(file)
45
+ } if exclude_dirs
43
46
 
44
47
  # Optionally use relative paths
45
- files.map! { |file| file.sub(/^#{Regexp.escape(base_dir)}\//, '') } if use_relative_paths
48
+ files.map! { |file|
49
+ file.sub(/^#{Regexp.escape(base_dir)}\//, '')
50
+ } if use_relative_paths
46
51
 
47
52
  matched_files += files
48
53
  end