markdown_exec 1.3.3.5 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -0
- data/CHANGELOG.md +14 -266
- data/Gemfile.lock +1 -1
- data/Rakefile +26 -596
- data/bin/tab_completion.sh +7 -7
- data/lib/block_label.rb +82 -0
- data/lib/env_opts.rb +6 -6
- data/lib/environment_opt_parse.rb +3 -3
- data/lib/fcb.rb +133 -0
- data/lib/filter.rb +181 -0
- data/lib/markdown_block_manager.rb +195 -0
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +74 -474
- data/lib/mdoc.rb +194 -0
- data/lib/menu.src.yml +448 -0
- data/lib/menu.yml +35 -9
- data/lib/menu_options.rb +0 -0
- data/lib/menu_options.yml +0 -0
- data/lib/object_present.rb +8 -8
- data/lib/option_value.rb +88 -0
- data/lib/regexp.rb +110 -0
- data/lib/saved_assets.rb +59 -0
- data/lib/saved_files_matcher.rb +61 -0
- metadata +14 -2
data/lib/markdown_exec.rb
CHANGED
@@ -12,10 +12,17 @@ require 'shellwords'
|
|
12
12
|
require 'tty-prompt'
|
13
13
|
require 'yaml'
|
14
14
|
|
15
|
+
require_relative 'block_label'
|
15
16
|
require_relative 'cached_nested_file_reader'
|
16
17
|
require_relative 'cli'
|
17
18
|
require_relative 'colorize'
|
18
19
|
require_relative 'env'
|
20
|
+
require_relative 'fcb'
|
21
|
+
require_relative 'filter'
|
22
|
+
require_relative 'mdoc'
|
23
|
+
require_relative 'option_value'
|
24
|
+
require_relative 'saved_assets'
|
25
|
+
require_relative 'saved_files_matcher'
|
19
26
|
require_relative 'shared'
|
20
27
|
require_relative 'tap'
|
21
28
|
require_relative 'markdown_exec/version'
|
@@ -90,14 +97,14 @@ public
|
|
90
97
|
|
91
98
|
# :reek:UtilityFunction
|
92
99
|
def list_recent_output(saved_stdout_folder, saved_stdout_glob, list_count)
|
93
|
-
|
94
|
-
|
100
|
+
SavedFilesMatcher.most_recent_list(saved_stdout_folder,
|
101
|
+
saved_stdout_glob, list_count)
|
95
102
|
end
|
96
103
|
|
97
104
|
# :reek:UtilityFunction
|
98
105
|
def list_recent_scripts(saved_script_folder, saved_script_glob, list_count)
|
99
|
-
|
100
|
-
|
106
|
+
SavedFilesMatcher.most_recent_list(saved_script_folder,
|
107
|
+
saved_script_glob, list_count)
|
101
108
|
end
|
102
109
|
|
103
110
|
# convert regex match groups to a hash with symbol keys
|
@@ -111,427 +118,9 @@ end
|
|
111
118
|
#
|
112
119
|
module MarkdownExec
|
113
120
|
# :reek:IrresponsibleModule
|
114
|
-
class Error < StandardError; end
|
115
|
-
|
116
|
-
# fenced code block
|
117
|
-
#
|
118
|
-
class FCB
|
119
|
-
def initialize(options = {})
|
120
|
-
@attrs = {
|
121
|
-
body: nil,
|
122
|
-
call: nil,
|
123
|
-
headings: [],
|
124
|
-
name: nil,
|
125
|
-
reqs: [],
|
126
|
-
shell: '',
|
127
|
-
title: '',
|
128
|
-
random: Random.new.rand,
|
129
|
-
text: nil # displayable in menu
|
130
|
-
}.merge options
|
131
|
-
end
|
132
|
-
|
133
|
-
def to_h
|
134
|
-
@attrs
|
135
|
-
end
|
136
|
-
|
137
|
-
def to_yaml
|
138
|
-
@attrs.to_yaml
|
139
|
-
end
|
140
|
-
|
141
|
-
private
|
142
|
-
|
143
|
-
# :reek:ManualDispatch
|
144
|
-
def method_missing(method, *args, &block)
|
145
|
-
method_name = method.to_s
|
146
|
-
|
147
|
-
if @attrs.respond_to?(method_name)
|
148
|
-
@attrs.send(method_name, *args, &block)
|
149
|
-
elsif method_name[-1] == '='
|
150
|
-
@attrs[method_name.chop.to_sym] = args[0]
|
151
|
-
else
|
152
|
-
@attrs[method_name.to_sym]
|
153
|
-
end
|
154
|
-
rescue StandardError => err
|
155
|
-
warn(error = "ERROR ** FCB.method_missing(method: #{method_name}," \
|
156
|
-
" *args: #{args.inspect}, &block)")
|
157
|
-
warn err.inspect
|
158
|
-
warn(caller[0..4])
|
159
|
-
raise StandardError, error
|
160
|
-
end
|
161
|
-
|
162
|
-
# option names are available as methods
|
163
|
-
#
|
164
|
-
def respond_to_missing?(_method_name, _include_private = false)
|
165
|
-
true # recognize all hash methods, rest are treated as hash keys
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
# select fcb per options
|
170
|
-
#
|
171
|
-
# :reek:UtilityFunction
|
172
|
-
class Filter
|
173
|
-
# def self.fcb_title_parse(opts, fcb_title)
|
174
|
-
# fcb_title.match(Regexp.new(opts[:fenced_start_ex_match])).named_captures.sym_keys
|
175
|
-
# end
|
176
|
-
|
177
|
-
def self.fcb_select?(options, fcb)
|
178
|
-
# options.tap_yaml 'options'
|
179
|
-
# fcb.tap_inspect 'fcb'
|
180
|
-
name = fcb.fetch(:name, '').tap_inspect 'name'
|
181
|
-
shell = fcb.fetch(:shell, '').tap_inspect 'shell'
|
182
|
-
|
183
|
-
## include hidden blocks for later use
|
184
|
-
#
|
185
|
-
name_default = true
|
186
|
-
name_exclude = nil
|
187
|
-
name_select = nil
|
188
|
-
shell_default = true
|
189
|
-
shell_exclude = nil
|
190
|
-
shell_select = nil
|
191
|
-
hidden_name = nil
|
192
|
-
|
193
|
-
if name.present? && options[:block_name]
|
194
|
-
if name =~ /#{options[:block_name]}/
|
195
|
-
'=~ block_name'.tap_puts
|
196
|
-
name_select = true
|
197
|
-
name_exclude = false
|
198
|
-
else
|
199
|
-
'!~ block_name'.tap_puts
|
200
|
-
name_exclude = true
|
201
|
-
name_select = false
|
202
|
-
end
|
203
|
-
end
|
204
|
-
|
205
|
-
if name.present? && name_select.nil? && options[:select_by_name_regex].present?
|
206
|
-
'+select_by_name_regex'.tap_puts
|
207
|
-
name_select = (!!(name =~ /#{options[:select_by_name_regex]}/)).tap_inspect 'name_select'
|
208
|
-
end
|
209
|
-
|
210
|
-
if shell.present? && options[:select_by_shell_regex].present?
|
211
|
-
'+select_by_shell_regex'.tap_puts
|
212
|
-
shell_select = (!!(shell =~ /#{options[:select_by_shell_regex]}/)).tap_inspect 'shell_select'
|
213
|
-
end
|
214
|
-
|
215
|
-
if name.present? && name_exclude.nil? && options[:exclude_by_name_regex].present?
|
216
|
-
'-exclude_by_name_regex'.tap_puts
|
217
|
-
name_exclude = (!!(name =~ /#{options[:exclude_by_name_regex]}/)).tap_inspect 'name_exclude'
|
218
|
-
end
|
219
|
-
|
220
|
-
if shell.present? && options[:exclude_by_shell_regex].present?
|
221
|
-
'-exclude_by_shell_regex'.tap_puts
|
222
|
-
shell_exclude = (!!(shell =~ /#{options[:exclude_by_shell_regex]}/)).tap_inspect 'shell_exclude'
|
223
|
-
end
|
224
|
-
|
225
|
-
if name.present? && options[:hide_blocks_by_name] &&
|
226
|
-
options[:block_name_hidden_match].present?
|
227
|
-
'+block_name_hidden_match'.tap_puts
|
228
|
-
hidden_name = (!!(name =~ /#{options[:block_name_hidden_match]}/)).tap_inspect 'hidden_name'
|
229
|
-
end
|
230
|
-
|
231
|
-
if shell.present? && options[:hide_blocks_by_shell] &&
|
232
|
-
options[:block_shell_hidden_match].present?
|
233
|
-
'-hide_blocks_by_shell'.tap_puts
|
234
|
-
(!!(shell =~ /#{options[:block_shell_hidden_match]}/)).tap_inspect 'hidden_shell'
|
235
|
-
end
|
236
|
-
|
237
|
-
if options[:bash_only]
|
238
|
-
'-bash_only'.tap_puts
|
239
|
-
shell_default = (shell == 'bash').tap_inspect 'shell_default'
|
240
|
-
end
|
241
|
-
|
242
|
-
## name matching does not filter hidden blocks
|
243
|
-
#
|
244
|
-
case
|
245
|
-
when options[:no_chrome] && fcb.fetch(:chrome, false)
|
246
|
-
'-no_chrome'.tap_puts
|
247
|
-
false
|
248
|
-
when options[:exclude_expect_blocks] && shell == 'expect'
|
249
|
-
'-exclude_expect_blocks'.tap_puts
|
250
|
-
false
|
251
|
-
when hidden_name == true
|
252
|
-
true
|
253
|
-
when name_exclude == true, shell_exclude == true,
|
254
|
-
name_select == false, shell_select == false
|
255
|
-
false
|
256
|
-
when name_select == true, shell_select == true
|
257
|
-
true
|
258
|
-
when name_default == false, shell_default == false
|
259
|
-
false
|
260
|
-
else
|
261
|
-
true
|
262
|
-
end.tap_inspect
|
263
|
-
rescue StandardError => err
|
264
|
-
warn("ERROR ** Filter::fcb_select?(); #{err.inspect}")
|
265
|
-
raise err
|
266
|
-
end
|
267
|
-
end # class Filter
|
268
|
-
|
269
|
-
## an imported markdown document
|
270
|
-
#
|
271
|
-
class MDoc
|
272
|
-
attr_reader :table
|
273
|
-
|
274
|
-
# convert block name to fcb_parse
|
275
|
-
#
|
276
|
-
def initialize(table)
|
277
|
-
@table = table
|
278
|
-
end
|
279
|
-
|
280
|
-
def collect_recursively_required_code(name)
|
281
|
-
get_required_blocks(name)
|
282
|
-
.map do |fcb|
|
283
|
-
body = fcb[:body].join("\n")
|
284
|
-
|
285
|
-
if fcb[:cann]
|
286
|
-
xcall = fcb[:cann][1..-2]
|
287
|
-
mstdin = xcall.match(/<(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
|
288
|
-
mstdout = xcall.match(/>(?<type>\$)?(?<name>[A-Za-z_\-.\w]+)/)
|
289
|
-
|
290
|
-
yqcmd = if mstdin[:type]
|
291
|
-
"echo \"$#{mstdin[:name]}\" | yq '#{body}'"
|
292
|
-
else
|
293
|
-
"yq e '#{body}' '#{mstdin[:name]}'"
|
294
|
-
end
|
295
|
-
if mstdout[:type]
|
296
|
-
"export #{mstdout[:name]}=$(#{yqcmd})"
|
297
|
-
else
|
298
|
-
"#{yqcmd} > '#{mstdout[:name]}'"
|
299
|
-
end
|
300
|
-
elsif fcb[:stdout]
|
301
|
-
stdout = fcb[:stdout]
|
302
|
-
body = fcb[:body].join("\n")
|
303
|
-
if stdout[:type]
|
304
|
-
%(export #{stdout[:name]}=$(cat <<"EOF"\n#{body}\nEOF\n))
|
305
|
-
else
|
306
|
-
"cat > '#{stdout[:name]}' <<\"EOF\"\n" \
|
307
|
-
"#{body}\n" \
|
308
|
-
"EOF\n"
|
309
|
-
end
|
310
|
-
else
|
311
|
-
fcb[:body]
|
312
|
-
end
|
313
|
-
end.flatten(1)
|
314
|
-
end
|
315
|
-
|
316
|
-
def get_block_by_name(name, default = {})
|
317
|
-
@table.select { |fcb| fcb.fetch(:name, '') == name }.fetch(0, default)
|
318
|
-
end
|
319
|
-
|
320
|
-
def get_required_blocks(name)
|
321
|
-
name_block = get_block_by_name(name)
|
322
|
-
raise "Named code block `#{name}` not found." if name_block.nil? || name_block.keys.empty?
|
323
|
-
|
324
|
-
all = [name_block.fetch(:name, '')] + recursively_required(name_block[:reqs])
|
325
|
-
|
326
|
-
# in order of appearance in document
|
327
|
-
# insert function blocks
|
328
|
-
@table.select { |fcb| all.include? fcb.fetch(:name, '') }
|
329
|
-
.map do |fcb|
|
330
|
-
if (call = fcb[:call])
|
331
|
-
[get_block_by_name("[#{call.match(/^%\((\S+) |\)/)[1]}]")
|
332
|
-
.merge({ cann: call })]
|
333
|
-
else
|
334
|
-
[]
|
335
|
-
end + [fcb]
|
336
|
-
end.flatten(1)
|
337
|
-
end
|
338
|
-
|
339
|
-
# :reek:UtilityFunction
|
340
|
-
def hide_menu_block_per_options(opts, block)
|
341
|
-
(opts[:hide_blocks_by_name] &&
|
342
|
-
block[:name]&.match(Regexp.new(opts[:block_name_hidden_match])) &&
|
343
|
-
(block[:name]&.present? || block[:label]&.present?)
|
344
|
-
).tap_inspect
|
345
|
-
end
|
346
|
-
|
347
|
-
# def blocks_for_menu(opts)
|
348
|
-
# if opts[:hide_blocks_by_name]
|
349
|
-
# @table.reject { |block| hide_menu_block_per_options opts, block }
|
350
|
-
# else
|
351
|
-
# @table
|
352
|
-
# end
|
353
|
-
# end
|
354
|
-
|
355
|
-
def fcbs_per_options(opts = {})
|
356
|
-
options = opts.merge(block_name_hidden_match: nil)
|
357
|
-
selrows = @table.select do |fcb_title_groups|
|
358
|
-
Filter.fcb_select? options, fcb_title_groups
|
359
|
-
end
|
360
|
-
|
361
|
-
### hide rows correctly
|
362
|
-
|
363
|
-
if opts[:hide_blocks_by_name]
|
364
|
-
selrows.reject { |block| hide_menu_block_per_options opts, block }
|
365
|
-
else
|
366
|
-
selrows
|
367
|
-
end.map do |block|
|
368
|
-
# block[:name] = block[:text] if block[:name].nil?
|
369
|
-
block
|
370
|
-
end
|
371
|
-
end
|
372
|
-
|
373
|
-
def recursively_required(reqs)
|
374
|
-
return [] unless reqs
|
375
|
-
|
376
|
-
rem = reqs
|
377
|
-
memo = []
|
378
|
-
while rem.count.positive?
|
379
|
-
rem = rem.map do |req|
|
380
|
-
next if memo.include? req
|
381
|
-
|
382
|
-
memo += [req]
|
383
|
-
get_block_by_name(req).fetch(:reqs, [])
|
384
|
-
end
|
385
|
-
.compact
|
386
|
-
.flatten(1)
|
387
|
-
end
|
388
|
-
memo
|
389
|
-
end
|
390
|
-
end # class MDoc
|
391
|
-
|
392
|
-
# format option defaults and values
|
393
|
-
#
|
394
|
-
# :reek:TooManyInstanceVariables
|
395
|
-
class BlockLabel
|
396
|
-
def initialize(filename:, headings:, menu_blocks_with_docname:,
|
397
|
-
menu_blocks_with_headings:, title:, body:, text:)
|
398
|
-
@filename = filename
|
399
|
-
@headings = headings
|
400
|
-
@menu_blocks_with_docname = menu_blocks_with_docname
|
401
|
-
@menu_blocks_with_headings = menu_blocks_with_headings
|
402
|
-
# @title = title.present? ? title : body
|
403
|
-
@title = title
|
404
|
-
@body = body
|
405
|
-
@text = text
|
406
|
-
rescue StandardError => err
|
407
|
-
warn(error = "ERROR ** BlockLabel.initialize(); #{err.inspect}")
|
408
|
-
binding.pry if $tap_enable
|
409
|
-
raise ArgumentError, error
|
410
|
-
end
|
411
|
-
|
412
|
-
# join title, headings, filename
|
413
|
-
#
|
414
|
-
def make
|
415
|
-
label = @title
|
416
|
-
label = @body unless label.present?
|
417
|
-
label = @text unless label.present?
|
418
|
-
label.tap_inspect
|
419
|
-
([label] +
|
420
|
-
(if @menu_blocks_with_headings
|
421
|
-
[@headings.compact.join(' # ')]
|
422
|
-
else
|
423
|
-
[]
|
424
|
-
end) +
|
425
|
-
(
|
426
|
-
if @menu_blocks_with_docname
|
427
|
-
[@filename]
|
428
|
-
else
|
429
|
-
[]
|
430
|
-
end
|
431
|
-
)).join(' ')
|
432
|
-
rescue StandardError => err
|
433
|
-
warn(error = "ERROR ** BlockLabel.make(); #{err.inspect}")
|
434
|
-
binding.pry if $tap_enable
|
435
|
-
raise ArgumentError, error
|
436
|
-
end
|
437
|
-
end # class BlockLabel
|
438
|
-
|
439
121
|
FNR11 = '/'
|
440
122
|
FNR12 = ',~'
|
441
123
|
|
442
|
-
# format option defaults and values
|
443
|
-
#
|
444
|
-
class SavedAsset
|
445
|
-
def initialize(filename:, prefix:, time:, blockname:)
|
446
|
-
@filename = filename
|
447
|
-
@prefix = prefix
|
448
|
-
@time = time
|
449
|
-
@blockname = blockname
|
450
|
-
end
|
451
|
-
|
452
|
-
def script_name
|
453
|
-
fne = @filename.gsub(FNR11, FNR12)
|
454
|
-
"#{[@prefix, @time.strftime('%F-%H-%M-%S'), fne, ',',
|
455
|
-
@blockname].join('_')}.sh"
|
456
|
-
end
|
457
|
-
|
458
|
-
def stdout_name
|
459
|
-
"#{[@prefix, @time.strftime('%F-%H-%M-%S'), @filename,
|
460
|
-
@blockname].join('_')}.out.txt"
|
461
|
-
end
|
462
|
-
end # class SavedAsset
|
463
|
-
|
464
|
-
# format option defaults and values
|
465
|
-
#
|
466
|
-
class OptionValue
|
467
|
-
def initialize(value)
|
468
|
-
@value = value
|
469
|
-
end
|
470
|
-
|
471
|
-
# as default value in env_str()
|
472
|
-
#
|
473
|
-
def for_hash(default = nil)
|
474
|
-
return default if @value.nil?
|
475
|
-
|
476
|
-
case @value.class.to_s
|
477
|
-
when 'String', 'Integer'
|
478
|
-
@value
|
479
|
-
when 'FalseClass', 'TrueClass'
|
480
|
-
@value ? true : false
|
481
|
-
when @value.empty?
|
482
|
-
default
|
483
|
-
else
|
484
|
-
@value.to_s
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
# for output as default value in list_default_yaml()
|
489
|
-
#
|
490
|
-
def for_yaml(default = nil)
|
491
|
-
return default if @value.nil?
|
492
|
-
|
493
|
-
case @value.class.to_s
|
494
|
-
when 'String'
|
495
|
-
"'#{@value}'"
|
496
|
-
when 'Integer'
|
497
|
-
@value
|
498
|
-
when 'FalseClass', 'TrueClass'
|
499
|
-
@value ? true : false
|
500
|
-
when @value.empty?
|
501
|
-
default
|
502
|
-
else
|
503
|
-
@value.to_s
|
504
|
-
end
|
505
|
-
end
|
506
|
-
end # class OptionValue
|
507
|
-
|
508
|
-
# a generated list of saved files
|
509
|
-
#
|
510
|
-
class Sfiles
|
511
|
-
def initialize(folder, glob)
|
512
|
-
@folder = folder
|
513
|
-
@glob = glob
|
514
|
-
end
|
515
|
-
|
516
|
-
def list_all
|
517
|
-
Dir.glob(File.join(@folder, @glob))
|
518
|
-
end
|
519
|
-
|
520
|
-
def most_recent(arr = nil)
|
521
|
-
arr = list_all if arr.nil?
|
522
|
-
return if arr.count < 1
|
523
|
-
|
524
|
-
arr.max
|
525
|
-
end
|
526
|
-
|
527
|
-
def most_recent_list(list_count, arr = nil)
|
528
|
-
arr = list_all if arr.nil?
|
529
|
-
return if (ac = arr.count) < 1
|
530
|
-
|
531
|
-
arr.sort[-[ac, list_count].min..].reverse
|
532
|
-
end
|
533
|
-
end # class Sfiles
|
534
|
-
|
535
124
|
##
|
536
125
|
#
|
537
126
|
# rubocop:disable Layout/LineLength
|
@@ -570,7 +159,7 @@ module MarkdownExec
|
|
570
159
|
[]
|
571
160
|
else
|
572
161
|
argv[0..ind - 1]
|
573
|
-
end
|
162
|
+
end
|
574
163
|
end
|
575
164
|
|
576
165
|
# return arguments after `--`
|
@@ -581,7 +170,7 @@ module MarkdownExec
|
|
581
170
|
[]
|
582
171
|
else
|
583
172
|
argv[ind + 1..-1]
|
584
|
-
end
|
173
|
+
end
|
585
174
|
end
|
586
175
|
|
587
176
|
##
|
@@ -589,16 +178,14 @@ module MarkdownExec
|
|
589
178
|
#
|
590
179
|
def base_options
|
591
180
|
menu_iter do |item|
|
592
|
-
# noisy item.tap_yaml name: :item
|
593
181
|
next unless item[:opt_name].present?
|
594
182
|
|
595
183
|
item_default = item[:default]
|
596
|
-
# noisy item_default.tap_inspect name: :item_default
|
597
184
|
value = if item_default.nil?
|
598
185
|
item_default
|
599
186
|
else
|
600
187
|
env_str(item[:env_var],
|
601
|
-
default: OptionValue.
|
188
|
+
default: OptionValue.for_hash(item_default))
|
602
189
|
end
|
603
190
|
[item[:opt_name], item[:proccode] ? item[:proccode].call(value) : value]
|
604
191
|
end.compact.to_h
|
@@ -757,7 +344,7 @@ module MarkdownExec
|
|
757
344
|
|
758
345
|
# :reek:DuplicateMethodCall
|
759
346
|
def exec_block(options, _block_name = '')
|
760
|
-
options = calculated_options.merge(options)
|
347
|
+
options = calculated_options.merge(options)
|
761
348
|
update_options options, over: false
|
762
349
|
|
763
350
|
# document and block reports
|
@@ -935,9 +522,11 @@ module MarkdownExec
|
|
935
522
|
# return body if not struct
|
936
523
|
#
|
937
524
|
def list_blocks_in_file(call_options = {}, &options_block)
|
938
|
-
opts = optsmerge(call_options, options_block)
|
525
|
+
opts = optsmerge(call_options, options_block)
|
526
|
+
use_chrome = !opts[:no_chrome]
|
527
|
+
|
939
528
|
blocks = []
|
940
|
-
if opts[:menu_initial_divider].present?
|
529
|
+
if opts[:menu_initial_divider].present? && use_chrome
|
941
530
|
blocks.push FCB.new({
|
942
531
|
# name: '',
|
943
532
|
chrome: true,
|
@@ -961,20 +550,26 @@ module MarkdownExec
|
|
961
550
|
#
|
962
551
|
if opts[:menu_divider_match].present? &&
|
963
552
|
(mbody = fcb.body[0].match opts[:menu_divider_match])
|
964
|
-
|
965
|
-
|
966
|
-
|
967
|
-
|
968
|
-
|
969
|
-
|
553
|
+
if use_chrome
|
554
|
+
blocks.push FCB.new(
|
555
|
+
{ chrome: true,
|
556
|
+
disabled: '',
|
557
|
+
name: format(opts[:menu_divider_format],
|
558
|
+
mbody[:name]).send(opts[:menu_divider_color].to_sym) }
|
559
|
+
)
|
560
|
+
end
|
970
561
|
elsif opts[:menu_task_match].present? &&
|
971
|
-
(
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
562
|
+
(fcb.body[0].match opts[:menu_task_match])
|
563
|
+
if use_chrome
|
564
|
+
blocks.push FCB.new(
|
565
|
+
{ chrome: true,
|
566
|
+
disabled: '',
|
567
|
+
name: format(
|
568
|
+
opts[:menu_task_format],
|
569
|
+
$~.named_captures.transform_keys(&:to_sym)
|
570
|
+
).send(opts[:menu_task_color].to_sym) }
|
571
|
+
)
|
572
|
+
end
|
978
573
|
else
|
979
574
|
# line not added
|
980
575
|
end
|
@@ -985,7 +580,7 @@ module MarkdownExec
|
|
985
580
|
end
|
986
581
|
end
|
987
582
|
|
988
|
-
if opts[:menu_divider_format].present? && opts[:menu_final_divider].present?
|
583
|
+
if opts[:menu_divider_format].present? && opts[:menu_final_divider].present? && use_chrome && use_chrome
|
989
584
|
blocks.push FCB.new(
|
990
585
|
{ chrome: true,
|
991
586
|
disabled: '',
|
@@ -994,7 +589,7 @@ module MarkdownExec
|
|
994
589
|
.send(opts[:menu_divider_color].to_sym) }
|
995
590
|
)
|
996
591
|
end
|
997
|
-
blocks
|
592
|
+
blocks
|
998
593
|
rescue StandardError => err
|
999
594
|
warn(error = "ERROR ** MarkParse.list_blocks_in_file(); #{err.inspect}")
|
1000
595
|
warn(caller[0..4])
|
@@ -1017,7 +612,7 @@ module MarkdownExec
|
|
1017
612
|
next unless item[:opt_name].present? && item[:default].present?
|
1018
613
|
|
1019
614
|
[
|
1020
|
-
"#{item[:opt_name]}: #{OptionValue.
|
615
|
+
"#{item[:opt_name]}: #{OptionValue.for_yaml(item[:default])}",
|
1021
616
|
item[:description].present? ? item[:description] : nil
|
1022
617
|
].compact.join(' # ')
|
1023
618
|
end.compact.sort
|
@@ -1074,7 +669,7 @@ module MarkdownExec
|
|
1074
669
|
blocks.map do |block|
|
1075
670
|
block.fetch(:text, nil) || block.fetch(:name, nil)
|
1076
671
|
end
|
1077
|
-
end.compact.reject(&:empty?)
|
672
|
+
end.compact.reject(&:empty?)
|
1078
673
|
end
|
1079
674
|
|
1080
675
|
## output type (body string or full object) per option struct and bash
|
@@ -1086,19 +681,21 @@ module MarkdownExec
|
|
1086
681
|
# fcb.fetch(:name, '') != '' && Filter.fcb_select?(opts, fcb)
|
1087
682
|
Filter.fcb_select?(opts.merge(no_chrome: true), fcb)
|
1088
683
|
end
|
1089
|
-
blocks_per_opts(blocks, opts)
|
684
|
+
blocks_per_opts(blocks, opts)
|
1090
685
|
end
|
1091
686
|
|
1092
687
|
def make_block_labels(call_options = {})
|
1093
688
|
opts = options.merge(call_options)
|
1094
689
|
list_blocks_in_file(opts).map do |fcb|
|
1095
|
-
BlockLabel.
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
690
|
+
BlockLabel.make(
|
691
|
+
filename: opts[:filename],
|
692
|
+
headings: fcb.fetch(:headings, []),
|
693
|
+
menu_blocks_with_docname: opts[:menu_blocks_with_docname],
|
694
|
+
menu_blocks_with_headings: opts[:menu_blocks_with_headings],
|
695
|
+
title: fcb[:title],
|
696
|
+
text: fcb[:text],
|
697
|
+
body: fcb[:body]
|
698
|
+
)
|
1102
699
|
end.compact
|
1103
700
|
end
|
1104
701
|
|
@@ -1352,8 +949,8 @@ module MarkdownExec
|
|
1352
949
|
end
|
1353
950
|
|
1354
951
|
def run_last_script
|
1355
|
-
filename =
|
1356
|
-
|
952
|
+
filename = SavedFilesMatcher.most_recent(@options[:saved_script_folder],
|
953
|
+
@options[:saved_script_glob])
|
1357
954
|
return unless filename
|
1358
955
|
|
1359
956
|
saved_name_split filename
|
@@ -1365,10 +962,10 @@ module MarkdownExec
|
|
1365
962
|
return unless @options[:save_execution_output]
|
1366
963
|
|
1367
964
|
@options[:logged_stdout_filename] =
|
1368
|
-
SavedAsset.
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
965
|
+
SavedAsset.stdout_name(blockname: @options[:block_name],
|
966
|
+
filename: File.basename(@options[:filename], '.*'),
|
967
|
+
prefix: @options[:logged_stdout_filename_prefix],
|
968
|
+
time: Time.now.utc)
|
1372
969
|
|
1373
970
|
@options[:logged_stdout_filespec] =
|
1374
971
|
File.join @options[:saved_stdout_folder],
|
@@ -1389,7 +986,7 @@ module MarkdownExec
|
|
1389
986
|
|
1390
987
|
def select_approve_and_execute_block(call_options, &options_block)
|
1391
988
|
opts = optsmerge call_options, options_block
|
1392
|
-
blocks_in_file = list_blocks_in_file(opts.merge(struct: true))
|
989
|
+
blocks_in_file = list_blocks_in_file(opts.merge(struct: true))
|
1393
990
|
mdoc = MDoc.new(blocks_in_file) do |nopts|
|
1394
991
|
opts.merge!(nopts)
|
1395
992
|
end
|
@@ -1405,7 +1002,7 @@ module MarkdownExec
|
|
1405
1002
|
# next unless fcb.fetch(:name, '').present?
|
1406
1003
|
|
1407
1004
|
fcb.merge!(
|
1408
|
-
label: BlockLabel.
|
1005
|
+
label: BlockLabel.make(
|
1409
1006
|
body: fcb[:body],
|
1410
1007
|
filename: opts[:filename],
|
1411
1008
|
headings: fcb.fetch(:headings, []),
|
@@ -1413,7 +1010,7 @@ module MarkdownExec
|
|
1413
1010
|
menu_blocks_with_headings: opts[:menu_blocks_with_headings],
|
1414
1011
|
text: fcb[:text],
|
1415
1012
|
title: fcb[:title]
|
1416
|
-
)
|
1013
|
+
)
|
1417
1014
|
)
|
1418
1015
|
|
1419
1016
|
fcb.to_h
|
@@ -1438,6 +1035,7 @@ module MarkdownExec
|
|
1438
1035
|
end
|
1439
1036
|
rescue StandardError => err
|
1440
1037
|
warn(error = "ERROR ** MarkParse.select_approve_and_execute_block(); #{err.inspect}")
|
1038
|
+
warn err.backtrace
|
1441
1039
|
binding.pry if $tap_enable
|
1442
1040
|
raise ArgumentError, error
|
1443
1041
|
end
|
@@ -1518,10 +1116,10 @@ module MarkdownExec
|
|
1518
1116
|
time_now = Time.now.utc
|
1519
1117
|
opts = optsmerge call_options
|
1520
1118
|
opts[:saved_script_filename] =
|
1521
|
-
SavedAsset.
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1119
|
+
SavedAsset.script_name(blockname: opts[:block_name],
|
1120
|
+
filename: opts[:filename],
|
1121
|
+
prefix: opts[:saved_script_filename_prefix],
|
1122
|
+
time: time_now)
|
1525
1123
|
|
1526
1124
|
@execute_script_filespec =
|
1527
1125
|
@options[:saved_filespec] =
|
@@ -1529,12 +1127,12 @@ module MarkdownExec
|
|
1529
1127
|
|
1530
1128
|
dirname = File.dirname(@options[:saved_filespec])
|
1531
1129
|
FileUtils.mkdir_p dirname
|
1532
|
-
|
1533
|
-
|
1534
|
-
|
1535
|
-
|
1536
|
-
|
1537
|
-
|
1130
|
+
shebang = if @options[:shebang]&.present?
|
1131
|
+
"#{@options[:shebang]} #{@options[:shell]}\n"
|
1132
|
+
else
|
1133
|
+
''
|
1134
|
+
end
|
1135
|
+
|
1538
1136
|
File.write(@options[:saved_filespec], shebang +
|
1539
1137
|
"# file_name: #{opts[:filename]}\n" \
|
1540
1138
|
"# block_name: #{opts[:block_name]}\n" \
|
@@ -1546,3 +1144,5 @@ module MarkdownExec
|
|
1546
1144
|
end
|
1547
1145
|
end # class MarkParse
|
1548
1146
|
end # module MarkdownExec
|
1147
|
+
|
1148
|
+
require 'minitest/autorun' if $PROGRAM_NAME == __FILE__
|