markdown_exec 1.6 → 1.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 +1 -1
- data/Gemfile.lock +1 -1
- data/Rakefile +1 -0
- data/bin/tab_completion.sh +2 -2
- data/examples/import0.md +41 -5
- data/examples/import1.md +9 -8
- data/examples/linked1.md +8 -4
- data/lib/array.rb +27 -0
- data/lib/array_util.rb +21 -0
- data/lib/cached_nested_file_reader.rb +51 -31
- data/lib/constants.rb +46 -0
- data/lib/env.rb +2 -1
- data/lib/exceptions.rb +34 -0
- data/lib/fcb.rb +41 -1
- data/lib/filter.rb +32 -17
- data/lib/fout.rb +52 -0
- data/lib/hash.rb +21 -0
- data/lib/hash_delegator.rb +2709 -0
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +137 -1458
- data/lib/mdoc.rb +0 -3
- data/lib/menu.src.yml +137 -27
- data/lib/menu.yml +131 -23
- data/lib/method_sorter.rb +19 -17
- data/lib/object_present.rb +1 -1
- data/lib/option_value.rb +4 -2
- data/lib/pty1.rb +16 -16
- data/lib/regexp.rb +4 -5
- data/lib/saved_assets.rb +4 -2
- data/lib/saved_files_matcher.rb +7 -3
- data/lib/shared.rb +0 -5
- data/lib/string_util.rb +22 -0
- data/lib/tap.rb +5 -2
- metadata +10 -3
- data/lib/environment_opt_parse.rb +0 -209
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97045160c53b7dca3998f6d700bf136f500826141d226f9f2cc650d15e6d1ba7
|
4
|
+
data.tar.gz: c69c23b07fcb3304d0209f79596619fbe54d0c2bb9a03f94c8598e3358c25ed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a525dc3c727c38aba2d52382871650b6d2636891028a6def27f8958fcd78ae46afcb8fbbeb0f1bfdb0d550beb22c7cc90c67744c52143490f0a27c75c9158442
|
7
|
+
data.tar.gz: ae304dc41d17d2763a17b518da50956f0271ca401a4bc78929200eeb17ab3d19dfd148db76f104aed8216120c38673d19c9e56af018d3c9d83534c8901cc0915
|
data/.rubocop.yml
CHANGED
data/Gemfile.lock
CHANGED
data/Rakefile
CHANGED
data/bin/tab_completion.sh
CHANGED
@@ -13,7 +13,7 @@ __filedirs_all()
|
|
13
13
|
}
|
14
14
|
|
15
15
|
_mde_echo_version() {
|
16
|
-
echo "1.
|
16
|
+
echo "1.7"
|
17
17
|
}
|
18
18
|
|
19
19
|
_mde() {
|
@@ -138,4 +138,4 @@ _mde() {
|
|
138
138
|
|
139
139
|
complete -o filenames -o nospace -F _mde mde
|
140
140
|
# _mde_echo_version
|
141
|
-
# echo "Updated: 2023-
|
141
|
+
# echo "Updated: 2023-12-01 18:34:38 UTC"
|
data/examples/import0.md
CHANGED
@@ -1,8 +1,44 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
```
|
1
|
+
This is Page 0
|
2
|
+
|
4
3
|
@import import1.md
|
5
|
-
|
6
|
-
|
4
|
+
|
5
|
+
```opts :(document_options)
|
6
|
+
user_must_approve: true
|
7
|
+
```
|
8
|
+
|
9
|
+
::: Page 0 code blocks
|
10
|
+
|
11
|
+
```bash :page0_block1 +(page0_block2) +(page1_block2)
|
12
|
+
echo "page 0 block 1 visible"
|
13
|
+
# requires page 0 block 2
|
14
|
+
# imports page 1
|
15
|
+
# requires page 1 block 2
|
16
|
+
```
|
17
|
+
|
18
|
+
```bash :(page0_block2)
|
19
|
+
echo "page 0 block 2 hidden"
|
7
20
|
```
|
8
21
|
|
22
|
+
::: Control display of code blocks
|
23
|
+
|
24
|
+
```opts :hide_imported_blocks
|
25
|
+
menu_include_imported_blocks: false
|
26
|
+
```
|
27
|
+
|
28
|
+
```opts :show_imported_blocks
|
29
|
+
menu_include_imported_blocks: true
|
30
|
+
```
|
31
|
+
|
32
|
+
::: Control display of notes
|
33
|
+
|
34
|
+
```opts :hide_imported_notes
|
35
|
+
menu_include_imported_notes: false
|
36
|
+
```
|
37
|
+
|
38
|
+
```opts :show_imported_notes
|
39
|
+
menu_include_imported_notes: true
|
40
|
+
```
|
41
|
+
|
42
|
+
```link :page_1
|
43
|
+
file: examples/import1.md
|
44
|
+
```
|
data/examples/import1.md
CHANGED
data/examples/linked1.md
CHANGED
@@ -11,16 +11,20 @@ colorize_env_vars 'vars for page2' PAGE2_VAR_VIA_INHERIT page2_var_via_environme
|
|
11
11
|
colorize_env_vars 'vars for page3' PAGE3_VAR_VIA_INHERIT page3_var_via_environment
|
12
12
|
```
|
13
13
|
|
14
|
+
```bash :(vars2)
|
15
|
+
PAGE2_VAR_VIA_INHERIT=for_page2_from_page1_via_inherited_code_file
|
16
|
+
```
|
17
|
+
|
18
|
+
```link :(linked2)
|
19
|
+
file: examples/linked2.md
|
20
|
+
```
|
21
|
+
|
14
22
|
::: This Link block
|
15
23
|
::: 1. requires a block that sets environment variable PAGE2_VAR_VIA_INHERIT,
|
16
24
|
::: 2. navigates to document 2, and
|
17
25
|
::: 3. executes block "show_vars" to display the imported PAGE2_VAR_VIA_INHERIT.
|
18
26
|
::: Any script generated by page 2 will contain the inherited code.
|
19
27
|
|
20
|
-
```bash :(vars2)
|
21
|
-
PAGE2_VAR_VIA_INHERIT=for_page2_from_page1_via_inherited_code_file
|
22
|
-
```
|
23
|
-
|
24
28
|
```link :linked2_import_vars +(vars2)
|
25
29
|
file: examples/linked2.md
|
26
30
|
block: show_vars
|
data/lib/array.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
class Array
|
7
|
+
# Processes each element of the array, yielding the previous, current, and next elements to the given block.
|
8
|
+
# Deletes the current element if the block returns true.
|
9
|
+
# @return [Array] The modified array after conditional deletions.
|
10
|
+
def process_and_conditionally_delete!
|
11
|
+
i = 0
|
12
|
+
while i < length
|
13
|
+
prev_item = self[i - 1] unless i.zero?
|
14
|
+
current_item = self[i]
|
15
|
+
next_item = self[i + 1]
|
16
|
+
|
17
|
+
should_delete = yield prev_item, current_item, next_item
|
18
|
+
if should_delete
|
19
|
+
delete_at(i)
|
20
|
+
else
|
21
|
+
i += 1
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
self
|
26
|
+
end
|
27
|
+
end
|
data/lib/array_util.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
module ArrayUtil
|
7
|
+
def self.partition_by_predicate(arr)
|
8
|
+
true_list = []
|
9
|
+
false_list = []
|
10
|
+
|
11
|
+
arr.each do |element|
|
12
|
+
if yield(element)
|
13
|
+
true_list << element
|
14
|
+
else
|
15
|
+
false_list << element
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
[true_list, false_list]
|
20
|
+
end
|
21
|
+
end
|
@@ -5,6 +5,16 @@
|
|
5
5
|
|
6
6
|
# version 2023-10-03
|
7
7
|
|
8
|
+
require 'fileutils'
|
9
|
+
require_relative 'exceptions'
|
10
|
+
|
11
|
+
# a struct to hold the data for a single line
|
12
|
+
NestedLine = Struct.new(:text, :depth) do
|
13
|
+
def to_s
|
14
|
+
text
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
8
18
|
##
|
9
19
|
# The CachedNestedFileReader class provides functionality to read file lines with the ability
|
10
20
|
# to process '#import filename' directives. When such a directive is encountered in a file,
|
@@ -13,42 +23,58 @@
|
|
13
23
|
# It allows clients to read lines with or without providing a block.
|
14
24
|
#
|
15
25
|
class CachedNestedFileReader
|
26
|
+
include Exceptions
|
27
|
+
|
16
28
|
def initialize(import_pattern: /^ *#import (.+)$/)
|
17
29
|
@file_cache = {}
|
18
30
|
@import_pattern = import_pattern
|
19
31
|
end
|
20
32
|
|
21
|
-
def
|
33
|
+
def error_handler(name = '', opts = {})
|
34
|
+
Exceptions.error_handler(
|
35
|
+
"CachedNestedFileReader.#{name} -- #{$!}",
|
36
|
+
opts
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
def warn_format(name, message, opts = {})
|
41
|
+
Exceptions.warn_format(
|
42
|
+
"CachedNestedFileReader.#{name} -- #{message}",
|
43
|
+
opts
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def readlines(filename, depth = 0, &block)
|
22
48
|
if @file_cache.key?(filename)
|
23
|
-
@file_cache[filename].each(&block) if
|
49
|
+
@file_cache[filename].each(&block) if block
|
24
50
|
return @file_cache[filename]
|
25
51
|
end
|
26
52
|
|
27
53
|
directory_path = File.dirname(filename)
|
28
|
-
lines = File.readlines(filename, chomp: true)
|
54
|
+
# lines = File.readlines(filename, chomp: true)
|
29
55
|
processed_lines = []
|
30
56
|
|
31
|
-
|
32
|
-
if
|
33
|
-
|
34
|
-
|
57
|
+
File.readlines(filename, chomp: true).each do |line|
|
58
|
+
if Regexp.new(@import_pattern) =~ line
|
59
|
+
name_strip = $~[:name].strip
|
60
|
+
included_file_path = if name_strip =~ %r{^/}
|
61
|
+
name_strip
|
35
62
|
else
|
36
|
-
File.join(directory_path,
|
63
|
+
File.join(directory_path, name_strip)
|
37
64
|
end
|
38
|
-
processed_lines += readlines(included_file_path,
|
65
|
+
processed_lines += readlines(included_file_path, depth + 1,
|
66
|
+
&block)
|
39
67
|
else
|
40
|
-
|
41
|
-
|
68
|
+
nested_line = NestedLine.new(line, depth)
|
69
|
+
processed_lines.push(nested_line)
|
70
|
+
block&.call(nested_line)
|
42
71
|
end
|
43
72
|
end
|
44
73
|
|
45
74
|
@file_cache[filename] = processed_lines
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
def fetch_lines(filename)
|
51
|
-
@fetch_lines_cache[filename] ||= File.readlines(filename, chomp: true)
|
75
|
+
rescue Errno::ENOENT
|
76
|
+
# Exceptions.error_handler('readlines', { abort: true })
|
77
|
+
warn_format('readlines', "No such file -- #{filename}", { abort: true })
|
52
78
|
end
|
53
79
|
end
|
54
80
|
|
@@ -56,10 +82,6 @@ if $PROGRAM_NAME == __FILE__
|
|
56
82
|
require 'minitest/autorun'
|
57
83
|
require 'tempfile'
|
58
84
|
|
59
|
-
##
|
60
|
-
# The CachedNestedFileReaderTest class provides testing for
|
61
|
-
# the CachedNestedFileReader class.
|
62
|
-
#
|
63
85
|
class CachedNestedFileReaderTest < Minitest::Test
|
64
86
|
def setup
|
65
87
|
@file2 = Tempfile.new('test2.txt')
|
@@ -69,7 +91,7 @@ if $PROGRAM_NAME == __FILE__
|
|
69
91
|
@file1 = Tempfile.new('test1.txt')
|
70
92
|
@file1.write("Line1\nLine2\n #insert #{@file2.path}\nLine3")
|
71
93
|
@file1.rewind
|
72
|
-
@reader = CachedNestedFileReader.new(import_pattern: /^ *#insert (.+)$/)
|
94
|
+
@reader = CachedNestedFileReader.new(import_pattern: /^ *#insert (?'name'.+)$/)
|
73
95
|
end
|
74
96
|
|
75
97
|
def teardown
|
@@ -81,28 +103,26 @@ if $PROGRAM_NAME == __FILE__
|
|
81
103
|
end
|
82
104
|
|
83
105
|
def test_readlines_without_imports
|
84
|
-
result =
|
85
|
-
@reader.readlines(@file2.path) { |line| result << line }
|
106
|
+
result = @reader.readlines(@file2.path).map(&:to_s)
|
86
107
|
assert_equal %w[ImportedLine1 ImportedLine2], result
|
87
108
|
end
|
88
109
|
|
89
110
|
def test_readlines_with_imports
|
90
|
-
result =
|
91
|
-
|
92
|
-
|
111
|
+
result = @reader.readlines(@file1.path).map(&:to_s)
|
112
|
+
assert_equal %w[Line1 Line2 ImportedLine1 ImportedLine2 Line3],
|
113
|
+
result
|
93
114
|
end
|
94
115
|
|
95
116
|
def test_caching_functionality
|
96
117
|
# First read
|
97
|
-
|
98
|
-
@reader.readlines(@file2.path)
|
118
|
+
|
119
|
+
result1 = @reader.readlines(@file2.path).map(&:to_s)
|
99
120
|
|
100
121
|
# Simulate file content change
|
101
122
|
@file2.reopen(@file2.path, 'w') { |f| f.write('ChangedLine') }
|
102
123
|
|
103
124
|
# Second read (should read from cache, not the changed file)
|
104
|
-
result2 =
|
105
|
-
@reader.readlines(@file2.path) { |line| result2 << line }
|
125
|
+
result2 = @reader.readlines(@file2.path).map(&:to_s)
|
106
126
|
|
107
127
|
assert_equal result1, result2
|
108
128
|
assert_equal %w[ImportedLine1 ImportedLine2], result2
|
data/lib/constants.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
class ExecutionStreams
|
7
|
+
StdErr = :stderr
|
8
|
+
StdIn = :stdin
|
9
|
+
StdOut = :stdout
|
10
|
+
end
|
11
|
+
|
12
|
+
class LoadFile
|
13
|
+
Load = true
|
14
|
+
Reuse = false
|
15
|
+
end
|
16
|
+
|
17
|
+
LoadFileNextBlock = Struct.new(:load_file, :next_block)
|
18
|
+
|
19
|
+
class MenuControl
|
20
|
+
Fresh = false
|
21
|
+
Repeat = true
|
22
|
+
end
|
23
|
+
|
24
|
+
class MenuOptions
|
25
|
+
YES = 1
|
26
|
+
NO = 2
|
27
|
+
SCRIPT_TO_CLIPBOARD = 3
|
28
|
+
SAVE_SCRIPT = 4
|
29
|
+
end
|
30
|
+
|
31
|
+
class MenuState
|
32
|
+
BACK = :back
|
33
|
+
CONTINUE = :continue
|
34
|
+
EXIT = :exit
|
35
|
+
end
|
36
|
+
|
37
|
+
# selected block and subsequent menu state
|
38
|
+
#
|
39
|
+
SelectedBlockMenuState = Struct.new(:block, :state)
|
40
|
+
|
41
|
+
SHELL_COLOR_OPTIONS = {
|
42
|
+
BlockType::BASH => :menu_bash_color,
|
43
|
+
BlockType::LINK => :menu_link_color,
|
44
|
+
BlockType::OPTS => :menu_opts_color,
|
45
|
+
BlockType::VARS => :menu_vars_color
|
46
|
+
}.freeze
|
data/lib/env.rb
CHANGED
@@ -18,7 +18,8 @@ module Env
|
|
18
18
|
|
19
19
|
# :reek:UtilityFunction
|
20
20
|
def env_bool_false(name)
|
21
|
-
!(val = (name && ENV.fetch(name,
|
21
|
+
!(val = (name && ENV.fetch(name,
|
22
|
+
nil))).nil? && !(val.empty? || val == '0')
|
22
23
|
end
|
23
24
|
|
24
25
|
# skip :reek:DataClump
|
data/lib/exceptions.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
module Exceptions
|
7
|
+
def self.error_handler(name = '', opts = {}, 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($@.select do |s|
|
11
|
+
s.include? 'markdown_exec'
|
12
|
+
end.reject { |s| s.include? 'vendor' }.take(take_count).map.with_index { |line, ind| " * #{ind}: #{line}" })
|
13
|
+
|
14
|
+
binding.pry if $tap_enable
|
15
|
+
raise ArgumentError, error unless opts.fetch(:abort, true)
|
16
|
+
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.warn_format(message = '', opts = {})
|
21
|
+
warn(
|
22
|
+
error = format(
|
23
|
+
opts.fetch(:format_string, "\nError: %{error}"),
|
24
|
+
{ error: message }
|
25
|
+
).send(opts.fetch(:color_symbol, :yellow))
|
26
|
+
)
|
27
|
+
# warn(caller.take(4).map.with_index { |line, ind| " * #{ind}: #{line}" })
|
28
|
+
|
29
|
+
binding.pry if $tap_enable
|
30
|
+
raise ArgumentError, error unless opts.fetch(:abort, false)
|
31
|
+
|
32
|
+
exit 1
|
33
|
+
end
|
34
|
+
end
|
data/lib/fcb.rb
CHANGED
@@ -19,6 +19,7 @@ module MarkdownExec
|
|
19
19
|
call: nil,
|
20
20
|
headings: [],
|
21
21
|
dname: nil,
|
22
|
+
indent: '',
|
22
23
|
name: nil,
|
23
24
|
oname: nil,
|
24
25
|
reqs: [],
|
@@ -29,6 +30,39 @@ module MarkdownExec
|
|
29
30
|
}.merge(options)
|
30
31
|
end
|
31
32
|
|
33
|
+
def title=(value)
|
34
|
+
@attrs[:title] = value
|
35
|
+
end
|
36
|
+
|
37
|
+
# Derives a title from the body of an FCB object.
|
38
|
+
# @param fcb [Object] The FCB object whose title is to be derived.
|
39
|
+
# @return [String] The derived title.
|
40
|
+
def derive_title_from_body
|
41
|
+
body_content = @attrs[:body]
|
42
|
+
unless body_content
|
43
|
+
@attrs[:title] = ''
|
44
|
+
return
|
45
|
+
end
|
46
|
+
|
47
|
+
@attrs[:title] = if body_content.count == 1
|
48
|
+
body_content.first
|
49
|
+
else
|
50
|
+
format_multiline_body_as_title(body_content)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
# Formats multiline body content as a title string.
|
57
|
+
# indents all but first line with two spaces so it displays correctly in menu
|
58
|
+
# @param body_lines [Array<String>] The lines of body content.
|
59
|
+
# @return [String] Formatted title.
|
60
|
+
def format_multiline_body_as_title(body_lines)
|
61
|
+
body_lines.map.with_index do |line, index|
|
62
|
+
index.zero? ? line : " #{line}"
|
63
|
+
end.join("\n") << "\n"
|
64
|
+
end
|
65
|
+
|
32
66
|
# :reek:ManualDispatch
|
33
67
|
def method_missing(method, *args, &block)
|
34
68
|
method_name = method.to_s
|
@@ -48,7 +82,9 @@ module MarkdownExec
|
|
48
82
|
raise err # Here, we simply propagate the original error instead of wrapping it in a StandardError.
|
49
83
|
end
|
50
84
|
|
51
|
-
|
85
|
+
public
|
86
|
+
|
87
|
+
def respond_to_missing?(method_name, include_private = false)
|
52
88
|
@attrs.key?(method_name.to_sym) || super
|
53
89
|
end
|
54
90
|
|
@@ -63,6 +99,9 @@ module MarkdownExec
|
|
63
99
|
end
|
64
100
|
|
65
101
|
if $PROGRAM_NAME == __FILE__
|
102
|
+
require 'bundler/setup'
|
103
|
+
Bundler.require(:default)
|
104
|
+
|
66
105
|
require 'minitest/autorun'
|
67
106
|
require 'yaml'
|
68
107
|
|
@@ -73,6 +112,7 @@ if $PROGRAM_NAME == __FILE__
|
|
73
112
|
call: 'Sample call',
|
74
113
|
headings: %w[Header1 Header2],
|
75
114
|
dname: 'Sample name',
|
115
|
+
indent: '',
|
76
116
|
name: 'Sample name',
|
77
117
|
oname: 'Sample name',
|
78
118
|
reqs: %w[req1 req2],
|
data/lib/filter.rb
CHANGED
@@ -38,14 +38,18 @@ module MarkdownExec
|
|
38
38
|
name = fcb.oname
|
39
39
|
shell = fcb.fetch(:shell, '')
|
40
40
|
|
41
|
+
### filter in menu, not in source code
|
42
|
+
filters[:depth] =
|
43
|
+
fcb.fetch(:depth,
|
44
|
+
0).positive? && !options[:menu_include_imported_blocks]
|
41
45
|
apply_name_filters(options, filters, name)
|
42
46
|
apply_shell_filters(options, filters, shell)
|
43
47
|
apply_other_filters(options, filters, fcb)
|
44
48
|
|
45
49
|
evaluate_filters(options, filters)
|
46
|
-
rescue StandardError
|
47
|
-
warn("ERROR ** Filter::fcb_select?(); #{
|
48
|
-
raise
|
50
|
+
rescue StandardError
|
51
|
+
warn("ERROR ** Filter::fcb_select?(); #{$!.inspect}")
|
52
|
+
raise ArgumentError, $!
|
49
53
|
end
|
50
54
|
|
51
55
|
# Applies name-based filters to determine whether to include or
|
@@ -68,14 +72,16 @@ module MarkdownExec
|
|
68
72
|
end
|
69
73
|
|
70
74
|
if name.present? && filters[:name_select].nil? && options[:select_by_name_regex].present?
|
71
|
-
filters[:name_select] =
|
75
|
+
filters[:name_select] =
|
76
|
+
!!(name =~ /#{options[:select_by_name_regex]}/)
|
72
77
|
end
|
73
78
|
|
74
79
|
unless name.present? && filters[:name_exclude].nil? && options[:exclude_by_name_regex].present?
|
75
80
|
return
|
76
81
|
end
|
77
82
|
|
78
|
-
filters[:name_exclude] =
|
83
|
+
filters[:name_exclude] =
|
84
|
+
!!(name =~ /#{options[:exclude_by_name_regex]}/)
|
79
85
|
end
|
80
86
|
|
81
87
|
# Applies shell-based filters to determine whether to include or
|
@@ -90,12 +96,16 @@ module MarkdownExec
|
|
90
96
|
filters[:shell_expect] = shell == 'expect'
|
91
97
|
|
92
98
|
if shell.present? && options[:select_by_shell_regex].present?
|
93
|
-
filters[:shell_select] =
|
99
|
+
filters[:shell_select] =
|
100
|
+
!!(shell =~ /#{options[:select_by_shell_regex]}/)
|
94
101
|
end
|
95
102
|
|
96
|
-
|
103
|
+
unless shell.present? && options[:exclude_by_shell_regex].present?
|
104
|
+
return
|
105
|
+
end
|
97
106
|
|
98
|
-
filters[:shell_exclude] =
|
107
|
+
filters[:shell_exclude] =
|
108
|
+
!!(shell =~ /#{options[:exclude_by_shell_regex]}/)
|
99
109
|
end
|
100
110
|
|
101
111
|
# Applies additional filters to determine whether to include or
|
@@ -138,7 +148,9 @@ module MarkdownExec
|
|
138
148
|
# if it should be excluded.
|
139
149
|
#
|
140
150
|
def self.evaluate_filters(options, filters)
|
141
|
-
if filters[:
|
151
|
+
if filters[:depth] == true
|
152
|
+
false
|
153
|
+
elsif filters[:fcb_chrome] == true
|
142
154
|
!options[:no_chrome]
|
143
155
|
elsif options[:exclude_expect_blocks] && filters[:shell_expect] == true
|
144
156
|
false
|
@@ -160,15 +172,18 @@ module MarkdownExec
|
|
160
172
|
end
|
161
173
|
end
|
162
174
|
|
163
|
-
#
|
164
|
-
# remove hidden blocks
|
175
|
+
# check if a block is not in the menu based on multiple match patterns
|
165
176
|
#
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
177
|
+
# @param options [Hash] Options hash containing various settings
|
178
|
+
# @param fcb [Hash] Hash representing a file code block
|
179
|
+
# @param match_patterns [Array<String>] Array of regular expression patterns for matching
|
180
|
+
# @return [Boolean] True if the block should not be in the menu, false otherwise
|
181
|
+
def self.prepared_not_in_menu?(options, fcb, match_patterns)
|
182
|
+
return false unless fcb[:shell] == BlockType::BASH
|
183
|
+
|
184
|
+
match_patterns.any? do |pattern|
|
185
|
+
options[pattern].present? && fcb[:oname] =~ /#{options[pattern]}/
|
186
|
+
end
|
172
187
|
end
|
173
188
|
end
|
174
189
|
end
|
data/lib/fout.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# encoding=utf-8
|
5
|
+
|
6
|
+
# stdout manager
|
7
|
+
#
|
8
|
+
# module FOut
|
9
|
+
class FOut
|
10
|
+
def initialize(config)
|
11
|
+
@config = config
|
12
|
+
end
|
13
|
+
|
14
|
+
def approved_fout?(level)
|
15
|
+
level <= fetch_display_level
|
16
|
+
end
|
17
|
+
|
18
|
+
# integer value for comparison
|
19
|
+
#
|
20
|
+
def fetch_display_level
|
21
|
+
@config.fetch(:display_level, 1)
|
22
|
+
end
|
23
|
+
|
24
|
+
# integer value for comparison
|
25
|
+
#
|
26
|
+
def fetch_display_level_xbase_prefix
|
27
|
+
@config.fetch(:level_xbase_prefix, '')
|
28
|
+
end
|
29
|
+
|
30
|
+
# standard output; not for debug
|
31
|
+
#
|
32
|
+
def fout(str)
|
33
|
+
puts str
|
34
|
+
end
|
35
|
+
|
36
|
+
def fout_list(str)
|
37
|
+
puts str
|
38
|
+
end
|
39
|
+
|
40
|
+
def fout_section(name, data)
|
41
|
+
puts "# #{name}"
|
42
|
+
puts data.to_yaml
|
43
|
+
end
|
44
|
+
|
45
|
+
# display output at level or lower than filter (DISPLAY_LEVEL_DEFAULT)
|
46
|
+
#
|
47
|
+
def lout(str, level: DISPLAY_LEVEL_BASE)
|
48
|
+
return unless approved_fout?(level)
|
49
|
+
|
50
|
+
fout level == DISPLAY_LEVEL_BASE ? str : fetch_display_level_xbase_prefix + str
|
51
|
+
end
|
52
|
+
end
|