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