markdown_exec 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (72) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +11 -2
  3. data/CHANGELOG.md +19 -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 +2 -2
  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 +39 -11
  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 +888 -603
  50. data/lib/hierarchy_string.rb +113 -25
  51. data/lib/input_sequencer.rb +16 -10
  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 +413 -165
  57. data/lib/mdoc.rb +27 -34
  58. data/lib/menu.src.yml +825 -710
  59. data/lib/menu.yml +799 -703
  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 +144 -8
  71. metadata +26 -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
 
@@ -102,16 +126,20 @@ class String
102
126
  def violet; fg_rgbh_94_00_D3; end
103
127
  def yellow; fg_rgbh_FF_FF_00; end
104
128
 
129
+ def x
130
+ pp [__LINE__, caller[1]]; binding.irb
131
+ end
132
+
105
133
  # graphics modes
106
- def bold; "\033[1m#{self}\033[22m"; end
107
- def bold_italic; "\033[1m\033[3m#{self}\033[22m\033[23m"; end
108
- def bold_underline; "\033[1m\033[4m#{self}\033[22m\033[24m"; end
109
- def dim; "\033[2m#{self}\033[22m"; end
110
- def italic; "\033[3m#{self}\033[23m"; end
111
- def underline; "\033[4m#{self}\033[24m"; end
112
- def underline_italic; "\033[4m\033[3m#{self}\033[23m\033[24m"; end
113
- def blinking; "\033[5m#{self}\033[25m"; end
114
- def inverse; "\033[7m#{self}\033[27m"; end
115
- def hidden; "\033[8m#{self}\033[28m"; end
116
- def strikethrough; "\033[9m#{self}\033[29m"; end
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
117
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