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.
- checksums.yaml +4 -4
- data/.rubocop.yml +11 -2
- data/CHANGELOG.md +19 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +32 -8
- data/bats/bats.bats +33 -0
- data/bats/block-types.bats +56 -0
- data/bats/cli.bats +74 -0
- data/bats/fail.bats +11 -0
- data/bats/history.bats +34 -0
- data/bats/markup.bats +66 -0
- data/bats/mde.bats +29 -0
- data/bats/options.bats +92 -0
- data/bats/test_helper.bash +152 -0
- data/bin/tab_completion.sh +44 -20
- data/docs/dev/block-type-opts.md +10 -0
- data/docs/dev/block-type-port.md +24 -0
- data/docs/dev/block-type-vars.md +7 -0
- data/docs/dev/pass-through-arguments.md +8 -0
- data/docs/dev/specs-import.md +9 -0
- data/docs/dev/specs.md +83 -0
- data/docs/dev/text-decoration.md +7 -0
- data/examples/bash-blocks.md +4 -4
- data/examples/block-names.md +2 -2
- data/examples/import0.md +23 -0
- data/examples/import1.md +13 -0
- data/examples/link-blocks-vars.md +3 -3
- data/examples/opts-blocks-require.md +6 -6
- data/examples/table-markup.md +31 -0
- data/examples/text-markup.md +58 -0
- data/examples/vars-blocks.md +2 -2
- data/examples/wrap.md +87 -9
- data/lib/ansi_formatter.rb +12 -6
- data/lib/ansi_string.rb +153 -0
- data/lib/argument_processor.rb +160 -0
- data/lib/cached_nested_file_reader.rb +4 -2
- data/lib/ce_get_cost_and_usage.rb +4 -3
- data/lib/cli.rb +1 -1
- data/lib/colorize.rb +39 -11
- data/lib/constants.rb +17 -0
- data/lib/directory_searcher.rb +4 -2
- data/lib/doh.rb +190 -0
- data/lib/env.rb +1 -1
- data/lib/exceptions.rb +9 -6
- data/lib/fcb.rb +0 -199
- data/lib/filter.rb +18 -5
- data/lib/find_files.rb +8 -3
- data/lib/format_table.rb +406 -0
- data/lib/hash_delegator.rb +888 -603
- data/lib/hierarchy_string.rb +113 -25
- data/lib/input_sequencer.rb +16 -10
- data/lib/instance_method_wrapper.rb +2 -1
- data/lib/layered_hash.rb +143 -0
- data/lib/link_history.rb +22 -8
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +413 -165
- data/lib/mdoc.rb +27 -34
- data/lib/menu.src.yml +825 -710
- data/lib/menu.yml +799 -703
- data/lib/namer.rb +6 -12
- data/lib/object_present.rb +1 -1
- data/lib/option_value.rb +7 -3
- data/lib/poly.rb +33 -14
- data/lib/resize_terminal.rb +60 -52
- data/lib/saved_assets.rb +45 -34
- data/lib/saved_files_matcher.rb +6 -3
- data/lib/streams_out.rb +7 -1
- data/lib/table_extractor.rb +166 -0
- data/lib/tap.rb +5 -6
- data/lib/text_analyzer.rb +144 -8
- metadata +26 -3
- data/lib/std_out_err_logger.rb +0 -119
@@ -0,0 +1,166 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class TableExtractor
|
4
|
+
# Extract tables from an array of text lines formatted in Markdown style
|
5
|
+
# @param [Array<String>] lines The array of text lines
|
6
|
+
# @return [Array<Hash>] An array of tables with row count, column count, and start index
|
7
|
+
def self.extract_tables(lines)
|
8
|
+
tables = []
|
9
|
+
inside_table = false
|
10
|
+
table_start = nil
|
11
|
+
row_count = 0
|
12
|
+
column_count = 0
|
13
|
+
|
14
|
+
separator_regexp = /^[ \t]*\|? *(?::?-+:?) *( *\| *(?::?-+:?) *)+\|? *$/
|
15
|
+
|
16
|
+
lines.each_with_index do |line, index|
|
17
|
+
# Match line separators with at least 2 columns
|
18
|
+
if line.strip.match?(separator_regexp)
|
19
|
+
if inside_table
|
20
|
+
# Add the current table before starting a new one
|
21
|
+
tables << {
|
22
|
+
rows: row_count,
|
23
|
+
columns: column_count,
|
24
|
+
start_index: table_start
|
25
|
+
}
|
26
|
+
end
|
27
|
+
# Start a new table
|
28
|
+
table_start = index - 1 if table_start.nil?
|
29
|
+
column_count = line.split('|').count - 1
|
30
|
+
row_count = 2 # Reset to 2 to account for the header and separator rows
|
31
|
+
inside_table = true
|
32
|
+
elsif inside_table && (line.strip.start_with?('|') || line.include?('|'))
|
33
|
+
row_count += 1
|
34
|
+
elsif inside_table
|
35
|
+
# Add the current table and reset the state
|
36
|
+
tables << {
|
37
|
+
rows: row_count,
|
38
|
+
columns: column_count,
|
39
|
+
start_index: table_start
|
40
|
+
}
|
41
|
+
inside_table = false
|
42
|
+
table_start = nil
|
43
|
+
row_count = 0
|
44
|
+
column_count = 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
# Handle case where table ends at the last line
|
49
|
+
if inside_table
|
50
|
+
tables << {
|
51
|
+
rows: row_count,
|
52
|
+
columns: column_count,
|
53
|
+
start_index: table_start
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
tables
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
return if $PROGRAM_NAME != __FILE__
|
62
|
+
|
63
|
+
require 'minitest/autorun'
|
64
|
+
|
65
|
+
class TestTableExtractor < Minitest::Test
|
66
|
+
def test_single_table
|
67
|
+
lines = [
|
68
|
+
'| Species| Genus| Family',
|
69
|
+
'|-|-|-',
|
70
|
+
'| Pongo tapanuliensis| Pongo| Hominidae',
|
71
|
+
'| | Histiophryne| Antennariidae'
|
72
|
+
]
|
73
|
+
expected = [{ rows: 4, columns: 3, start_index: 0 }]
|
74
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_indented_table
|
78
|
+
lines = [
|
79
|
+
"\t | Species| Genus| Family",
|
80
|
+
"\t |-|-|-",
|
81
|
+
"\t | Pongo tapanuliensis| Pongo| Hominidae",
|
82
|
+
"\t | | Histiophryne| Antennariidae"
|
83
|
+
]
|
84
|
+
expected = [{ rows: 4, columns: 3, start_index: 0 }]
|
85
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
86
|
+
end
|
87
|
+
|
88
|
+
def test_multiple_tables
|
89
|
+
lines = [
|
90
|
+
'| Species| Genus| Family',
|
91
|
+
'|-|-|-',
|
92
|
+
'| Pongo tapanuliensis| Pongo| Hominidae',
|
93
|
+
'| | Histiophryne| Antennariidae',
|
94
|
+
'',
|
95
|
+
'| Name| Species',
|
96
|
+
'|-|-',
|
97
|
+
'| Tapanuli Orangutan| Pongo tapanuliensis'
|
98
|
+
]
|
99
|
+
expected = [
|
100
|
+
{ rows: 4, columns: 3, start_index: 0 },
|
101
|
+
{ rows: 3, columns: 2, start_index: 5 }
|
102
|
+
]
|
103
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_no_tables
|
107
|
+
lines = [
|
108
|
+
'This is a regular line.',
|
109
|
+
'Another regular line.'
|
110
|
+
]
|
111
|
+
expected = []
|
112
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_inconsistent_columns
|
116
|
+
lines = [
|
117
|
+
'| Species| Genus| Family',
|
118
|
+
'|-|-',
|
119
|
+
'| Pongo tapanuliensis| Pongo| Hominidae',
|
120
|
+
'| | Histiophryne| Antennariidae',
|
121
|
+
'',
|
122
|
+
'| Name| Species',
|
123
|
+
'|-|-|-',
|
124
|
+
'| Tapanuli Orangutan| Pongo tapanuliensis'
|
125
|
+
]
|
126
|
+
# number of columns determined from row of dividers
|
127
|
+
expected = [{ rows: 4, columns: 2, start_index: 0 },
|
128
|
+
{ rows: 3, columns: 3, start_index: 5 }]
|
129
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
130
|
+
end
|
131
|
+
|
132
|
+
def test_table_at_end_of_lines
|
133
|
+
lines = [
|
134
|
+
'Some introductory text.',
|
135
|
+
'| Species| Genus| Family',
|
136
|
+
'|-|-|-',
|
137
|
+
'| Pongo tapanuliensis| Pongo| Hominidae',
|
138
|
+
'| | Histiophryne| Antennariidae'
|
139
|
+
]
|
140
|
+
expected = [{ rows: 4, columns: 3, start_index: 1 }]
|
141
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_table_without_starting_pipe
|
145
|
+
lines = [
|
146
|
+
'Some introductory text.',
|
147
|
+
'Platform| Target Environment| Command',
|
148
|
+
'|-|-|-',
|
149
|
+
'| Pongo tapanuliensis| Pongo| Hominidae',
|
150
|
+
'| | Histiophryne| Antennariidae'
|
151
|
+
]
|
152
|
+
expected = [{ rows: 4, columns: 3, start_index: 1 }]
|
153
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_table_with_colon_hyphens
|
157
|
+
lines = [
|
158
|
+
'| Name| Age| City',
|
159
|
+
'|:-:|:-|:-:',
|
160
|
+
'| John Doe| 30| New York',
|
161
|
+
'| Jane Doe| 25| Los Angeles'
|
162
|
+
]
|
163
|
+
expected = [{ rows: 4, columns: 3, start_index: 0 }]
|
164
|
+
assert_equal expected, TableExtractor.extract_tables(lines)
|
165
|
+
end
|
166
|
+
end
|
data/lib/tap.rb
CHANGED
@@ -35,8 +35,6 @@ unless defined?(Env)
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
# rubocop:disable Metrics/ParameterLists
|
39
|
-
|
40
38
|
## application-level debug control
|
41
39
|
#
|
42
40
|
# :reek:TooManyConstants
|
@@ -98,8 +96,8 @@ module Tap
|
|
98
96
|
|
99
97
|
# :reek:ControlParameter
|
100
98
|
# :reek:LongParameterList
|
101
|
-
def tap_inspect(name_ = nil, caller_first: nil, mask: TDD, name: DN,
|
102
|
-
type: nil)
|
99
|
+
def tap_inspect(name_ = nil, caller_first: nil, mask: TDD, name: DN,
|
100
|
+
source: nil, type: nil)
|
103
101
|
return self unless $tap_enable
|
104
102
|
return self unless (mask & $tap_mask).positive?
|
105
103
|
|
@@ -107,7 +105,8 @@ module Tap
|
|
107
105
|
outs = []
|
108
106
|
outs.push(source.to_s) if source.present?
|
109
107
|
|
110
|
-
vs = (caller_first || caller[0]).scan(/in `?(\S+)'$/)
|
108
|
+
vs = (caller_first || caller[0]).scan(/in `?(\S+)'$/)
|
109
|
+
.fetch(0, []).fetch(0, '')
|
111
110
|
outs.push("#{vs}()") if vs.present?
|
112
111
|
|
113
112
|
outs.push(tap_named_value(name_ || name, method(fn).call))
|
@@ -143,7 +142,7 @@ module Tap
|
|
143
142
|
# :reek:ControlParameter
|
144
143
|
# :reek:LongParameterList
|
145
144
|
def tap_yaml(name_ = nil, caller_first: nil, mask: TDD, name: DN, source: nil)
|
146
|
-
tap_inspect name_, caller_first:
|
145
|
+
tap_inspect name_, caller_first: caller_first || caller[0],
|
147
146
|
mask: mask, name: name, source: source, type: :yaml
|
148
147
|
end
|
149
148
|
|
data/lib/text_analyzer.rb
CHANGED
@@ -11,13 +11,17 @@ module TextAnalyzer
|
|
11
11
|
# @return [Array<Hash>, Array<Array<Hash>>] an array or nested arrays of highlighted segments
|
12
12
|
#
|
13
13
|
# @raise [ArgumentError] if the hierarchy structure is neither a String nor an Array
|
14
|
-
def self.analyze_hierarchy(
|
14
|
+
def self.analyze_hierarchy(
|
15
|
+
hierarchy, pattern, default_color, match_color,
|
16
|
+
text_sym: :text, style_sym: :color
|
17
|
+
)
|
15
18
|
case hierarchy
|
16
19
|
when String
|
17
20
|
highlight_segments(hierarchy, pattern, default_color, match_color)
|
21
|
+
|
18
22
|
when Hash
|
19
|
-
decorated = highlight_segments(hierarchy[
|
20
|
-
hierarchy[
|
23
|
+
decorated = highlight_segments(hierarchy[text_sym], pattern,
|
24
|
+
hierarchy[style_sym], match_color)
|
21
25
|
|
22
26
|
case decorated
|
23
27
|
when String
|
@@ -31,18 +35,19 @@ module TextAnalyzer
|
|
31
35
|
else
|
32
36
|
decorated
|
33
37
|
end
|
38
|
+
|
34
39
|
when Array
|
35
40
|
hierarchy.map do |element|
|
36
41
|
analyze_hierarchy(element, pattern, default_color, match_color)
|
37
42
|
end
|
38
|
-
when HierarchyString
|
39
43
|
|
44
|
+
when HierarchyString
|
40
45
|
hierarchy.replace_text! do |substring|
|
41
|
-
substring
|
46
|
+
substring # no change
|
42
47
|
end
|
43
48
|
|
44
49
|
else
|
45
|
-
|
50
|
+
warn [hierarchy.class, hierarchy].inspect
|
46
51
|
raise ArgumentError, 'Invalid hierarchy structure'
|
47
52
|
end
|
48
53
|
end
|
@@ -77,14 +82,14 @@ module TextAnalyzer
|
|
77
82
|
# @yieldparam segment [String] a segment of the text
|
78
83
|
# @yieldparam is_match [Boolean] true if the segment matches the pattern, false otherwise
|
79
84
|
def self.yield_matches_and_non_matches(text, pattern)
|
80
|
-
last_end =
|
85
|
+
last_end = nil
|
81
86
|
|
82
87
|
text.scan(pattern) do |match|
|
83
88
|
match_start = Regexp.last_match.begin(0)
|
84
89
|
match_end = Regexp.last_match.end(0)
|
85
90
|
|
86
91
|
# Yield the non-matching segment before the match
|
87
|
-
yield text[last_end...match_start], false if match_start > last_end
|
92
|
+
yield text[(last_end || 0)...match_start], false if last_end.nil? || match_start > last_end
|
88
93
|
|
89
94
|
# Yield the matching segment
|
90
95
|
yield match.first, true
|
@@ -92,9 +97,140 @@ module TextAnalyzer
|
|
92
97
|
last_end = match_end
|
93
98
|
end
|
94
99
|
|
100
|
+
last_end ||= 0
|
95
101
|
# Yield any remaining non-matching segment after the last match
|
96
102
|
return unless last_end < text.length
|
97
103
|
|
98
104
|
yield text[last_end..-1], false
|
99
105
|
end
|
100
106
|
end
|
107
|
+
|
108
|
+
return if $PROGRAM_NAME != __FILE__
|
109
|
+
|
110
|
+
require 'minitest/autorun'
|
111
|
+
require_relative 'hierarchy_string'
|
112
|
+
|
113
|
+
$default_color = :upcase
|
114
|
+
$match_color = :downcase
|
115
|
+
|
116
|
+
class TestTextAnalyzer < Minitest::Test
|
117
|
+
def test_analyze_hierarchy_with_string
|
118
|
+
text = 'This is a test string.'
|
119
|
+
pattern = /(test)/
|
120
|
+
|
121
|
+
expected_output = [[[
|
122
|
+
{ text: 'This is a ', color: $default_color },
|
123
|
+
{ text: 'test', color: $match_color },
|
124
|
+
{ text: ' string.', color: $default_color }
|
125
|
+
]]]
|
126
|
+
|
127
|
+
tree = HierarchyString.new([{ text: text, color: $default_color }])
|
128
|
+
assert_equal expected_output,
|
129
|
+
TextAnalyzer.analyze_hierarchy(tree.substrings, pattern, $default_color,
|
130
|
+
$match_color)
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_analyze_hierarchy_with_array
|
134
|
+
hierarchy = [
|
135
|
+
'This is a test string.',
|
136
|
+
'Another test line.'
|
137
|
+
]
|
138
|
+
pattern = /(test)/
|
139
|
+
|
140
|
+
expected_output = [
|
141
|
+
[
|
142
|
+
{ text: 'This is a ', color: $default_color },
|
143
|
+
{ text: 'test', color: $match_color },
|
144
|
+
{ text: ' string.', color: $default_color }
|
145
|
+
],
|
146
|
+
[
|
147
|
+
{ text: 'Another ', color: $default_color },
|
148
|
+
{ text: 'test', color: $match_color },
|
149
|
+
{ text: ' line.', color: $default_color }
|
150
|
+
]
|
151
|
+
]
|
152
|
+
|
153
|
+
assert_equal expected_output,
|
154
|
+
TextAnalyzer.analyze_hierarchy(hierarchy, pattern,
|
155
|
+
$default_color, $match_color)
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_analyze_hierarchy_with_nested_array
|
159
|
+
hierarchy = [
|
160
|
+
'This is a test string.',
|
161
|
+
['Another test line.', 'Yet another test.']
|
162
|
+
]
|
163
|
+
pattern = /(test)/
|
164
|
+
|
165
|
+
expected_output = [
|
166
|
+
[
|
167
|
+
{ text: 'This is a ', color: $default_color },
|
168
|
+
{ text: 'test', color: $match_color },
|
169
|
+
{ text: ' string.', color: $default_color }
|
170
|
+
],
|
171
|
+
[
|
172
|
+
[
|
173
|
+
{ text: 'Another ', color: $default_color },
|
174
|
+
{ text: 'test', color: $match_color },
|
175
|
+
{ text: ' line.', color: $default_color }
|
176
|
+
],
|
177
|
+
[
|
178
|
+
{ text: 'Yet another ', color: $default_color },
|
179
|
+
{ text: 'test', color: $match_color },
|
180
|
+
{ text: '.', color: $default_color }
|
181
|
+
]
|
182
|
+
]
|
183
|
+
]
|
184
|
+
|
185
|
+
assert_equal expected_output,
|
186
|
+
TextAnalyzer.analyze_hierarchy(hierarchy, pattern,
|
187
|
+
$default_color, $match_color)
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_analyze_hierarchy_with_invalid_type
|
191
|
+
hierarchy = 12_345
|
192
|
+
# hierarchy = HierarchyString.new([{ text: '12345', color: $default_color }])
|
193
|
+
pattern = /(test)/
|
194
|
+
|
195
|
+
assert_raises(ArgumentError) do
|
196
|
+
TextAnalyzer.analyze_hierarchy(hierarchy, pattern, $default_color,
|
197
|
+
$match_color)
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
def test_highlight_segments
|
202
|
+
text = 'This is a test string.'
|
203
|
+
pattern = /(test)/
|
204
|
+
|
205
|
+
expected_output = [
|
206
|
+
{ text: 'This is a ', color: $default_color },
|
207
|
+
{ text: 'test', color: $match_color },
|
208
|
+
{ text: ' string.', color: $default_color }
|
209
|
+
]
|
210
|
+
|
211
|
+
assert_equal expected_output,
|
212
|
+
TextAnalyzer.highlight_segments(text, pattern, $default_color,
|
213
|
+
$match_color)
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_yield_matches_and_non_matches
|
217
|
+
text = 'This is a test string with multiple tests.'
|
218
|
+
pattern = /(test)/
|
219
|
+
segments = []
|
220
|
+
|
221
|
+
TextAnalyzer.yield_matches_and_non_matches(text,
|
222
|
+
pattern) do |segment, is_match|
|
223
|
+
segments << { text: segment, is_match: is_match }
|
224
|
+
end
|
225
|
+
|
226
|
+
expected_output = [
|
227
|
+
{ text: 'This is a ', is_match: false },
|
228
|
+
{ text: 'test', is_match: true },
|
229
|
+
{ text: ' string with multiple ', is_match: false },
|
230
|
+
{ text: 'test', is_match: true },
|
231
|
+
{ text: 's.', is_match: false }
|
232
|
+
]
|
233
|
+
|
234
|
+
assert_equal expected_output, segments
|
235
|
+
end
|
236
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: markdown_exec
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fareed Stevenson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-09-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: clipboard
|
@@ -106,6 +106,15 @@ files:
|
|
106
106
|
- assets/output_of_execution.png
|
107
107
|
- assets/select_a_block.png
|
108
108
|
- assets/select_a_file.png
|
109
|
+
- bats/bats.bats
|
110
|
+
- bats/block-types.bats
|
111
|
+
- bats/cli.bats
|
112
|
+
- bats/fail.bats
|
113
|
+
- bats/history.bats
|
114
|
+
- bats/markup.bats
|
115
|
+
- bats/mde.bats
|
116
|
+
- bats/options.bats
|
117
|
+
- bats/test_helper.bash
|
109
118
|
- bin/bmde
|
110
119
|
- bin/colorize_env_vars.sh
|
111
120
|
- bin/console
|
@@ -113,6 +122,13 @@ files:
|
|
113
122
|
- bin/setup
|
114
123
|
- bin/tab_completion.sh
|
115
124
|
- bin/tab_completion.sh.erb
|
125
|
+
- docs/dev/block-type-opts.md
|
126
|
+
- docs/dev/block-type-port.md
|
127
|
+
- docs/dev/block-type-vars.md
|
128
|
+
- docs/dev/pass-through-arguments.md
|
129
|
+
- docs/dev/specs-import.md
|
130
|
+
- docs/dev/specs.md
|
131
|
+
- docs/dev/text-decoration.md
|
116
132
|
- examples/bash-blocks.md
|
117
133
|
- examples/block-names.md
|
118
134
|
- examples/block_names.md
|
@@ -149,9 +165,13 @@ files:
|
|
149
165
|
- examples/port-blocks.md
|
150
166
|
- examples/save.md
|
151
167
|
- examples/search.md
|
168
|
+
- examples/table-markup.md
|
169
|
+
- examples/text-markup.md
|
152
170
|
- examples/vars-blocks.md
|
153
171
|
- examples/wrap.md
|
154
172
|
- lib/ansi_formatter.rb
|
173
|
+
- lib/ansi_string.rb
|
174
|
+
- lib/argument_processor.rb
|
155
175
|
- lib/array.rb
|
156
176
|
- lib/array_util.rb
|
157
177
|
- lib/block_label.rb
|
@@ -163,17 +183,20 @@ files:
|
|
163
183
|
- lib/colorize.rb
|
164
184
|
- lib/constants.rb
|
165
185
|
- lib/directory_searcher.rb
|
186
|
+
- lib/doh.rb
|
166
187
|
- lib/env.rb
|
167
188
|
- lib/exceptions.rb
|
168
189
|
- lib/fcb.rb
|
169
190
|
- lib/filter.rb
|
170
191
|
- lib/find_files.rb
|
192
|
+
- lib/format_table.rb
|
171
193
|
- lib/fout.rb
|
172
194
|
- lib/hash.rb
|
173
195
|
- lib/hash_delegator.rb
|
174
196
|
- lib/hierarchy_string.rb
|
175
197
|
- lib/input_sequencer.rb
|
176
198
|
- lib/instance_method_wrapper.rb
|
199
|
+
- lib/layered_hash.rb
|
177
200
|
- lib/link_history.rb
|
178
201
|
- lib/markdown_exec.rb
|
179
202
|
- lib/markdown_exec/version.rb
|
@@ -190,9 +213,9 @@ files:
|
|
190
213
|
- lib/saved_assets.rb
|
191
214
|
- lib/saved_files_matcher.rb
|
192
215
|
- lib/shared.rb
|
193
|
-
- lib/std_out_err_logger.rb
|
194
216
|
- lib/streams_out.rb
|
195
217
|
- lib/string_util.rb
|
218
|
+
- lib/table_extractor.rb
|
196
219
|
- lib/tap.rb
|
197
220
|
- lib/text_analyzer.rb
|
198
221
|
homepage: https://rubygems.org/gems/markdown_exec
|
data/lib/std_out_err_logger.rb
DELETED
@@ -1,119 +0,0 @@
|
|
1
|
-
#!/usr/bin/env -S bundle exec ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
# encoding=utf-8
|
5
|
-
require 'logger'
|
6
|
-
|
7
|
-
# Logger::LogDevice is used by Logger, the parent class of StdOutErrLogger
|
8
|
-
class Logger::LogDevice
|
9
|
-
# remove header
|
10
|
-
def add_log_header(file); end
|
11
|
-
end
|
12
|
-
|
13
|
-
# Custom logger to direct info to stdout and warn and above to stderr
|
14
|
-
#
|
15
|
-
class StdOutErrLogger < Logger
|
16
|
-
attr_reader :file
|
17
|
-
|
18
|
-
# def initialize(file = nil)
|
19
|
-
def initialize(file = "#{__dir__}/../tmp/hash_delegator_next_link_state.yaml")
|
20
|
-
@file = file
|
21
|
-
super(file || $stdout)
|
22
|
-
self.formatter = proc do |_severity, _datetime, _progname, msg|
|
23
|
-
"#{msg}\n"
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def add(severity, message = nil, progname = nil, &block)
|
28
|
-
message = (message || block&.call || progname) if message.nil?
|
29
|
-
message = "- #{message.to_json}\n"
|
30
|
-
### message = message.join("\n") if message.is_a? Array
|
31
|
-
out = format_message(format_severity(severity), Time.now, progname, message)
|
32
|
-
if severity == Logger::UNKNOWN # does not follow spec, outputs to stderr for IO
|
33
|
-
# $stderr.puts(out)
|
34
|
-
super
|
35
|
-
elsif severity >= Logger::WARN
|
36
|
-
if @file
|
37
|
-
super
|
38
|
-
else
|
39
|
-
warn(out)
|
40
|
-
end
|
41
|
-
elsif @file
|
42
|
-
super
|
43
|
-
else
|
44
|
-
$stdout.puts(out)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
return if $PROGRAM_NAME != __FILE__
|
50
|
-
|
51
|
-
require 'minitest/autorun'
|
52
|
-
|
53
|
-
class StdOutErrLoggerTest < Minitest::Test
|
54
|
-
# Redirect STDOUT and STDERR to capture them for assertions
|
55
|
-
def setup
|
56
|
-
@original_stdout = $stdout
|
57
|
-
@original_stderr = $stderr
|
58
|
-
$stdout = StringIO.new
|
59
|
-
$stderr = StringIO.new
|
60
|
-
end
|
61
|
-
|
62
|
-
def teardown
|
63
|
-
$stdout = @original_stdout
|
64
|
-
$stderr = @original_stderr
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_initialize_without_file
|
68
|
-
logger = StdOutErrLogger.new
|
69
|
-
assert_nil logger.file
|
70
|
-
assert_equal Logger::DEBUG, logger.level
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_initialize_with_file
|
74
|
-
Tempfile.open do |file|
|
75
|
-
logger = StdOutErrLogger.new(file.path)
|
76
|
-
assert_equal file.path, logger.file
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_logging_info
|
81
|
-
logger = StdOutErrLogger.new
|
82
|
-
logger.info('Info message')
|
83
|
-
assert_equal "Info message\n", $stdout.string
|
84
|
-
assert_empty $stderr.string
|
85
|
-
end
|
86
|
-
|
87
|
-
def test_logging_warning
|
88
|
-
logger = StdOutErrLogger.new
|
89
|
-
logger.warn('Warning message')
|
90
|
-
assert_empty $stdout.string
|
91
|
-
assert_equal "Warning message\n", $stderr.string
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_logging_error
|
95
|
-
logger = StdOutErrLogger.new
|
96
|
-
logger.error('Error message')
|
97
|
-
assert_empty $stdout.string
|
98
|
-
assert_equal "Error message\n", $stderr.string
|
99
|
-
end
|
100
|
-
|
101
|
-
def test_logging_with_array
|
102
|
-
logger = StdOutErrLogger.new
|
103
|
-
logger.info(['Message line 1', 'Message line 2'])
|
104
|
-
assert_equal "Message line 1\nMessage line 2\n", $stdout.string
|
105
|
-
end
|
106
|
-
|
107
|
-
def test_logging_with_block
|
108
|
-
logger = StdOutErrLogger.new
|
109
|
-
logger.info { 'Block message' }
|
110
|
-
assert_equal "Block message\n", $stdout.string
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_logging_unknown_severity
|
114
|
-
logger = StdOutErrLogger.new
|
115
|
-
logger.add(Logger::UNKNOWN, 'Unknown severity message')
|
116
|
-
assert_empty $stdout.string
|
117
|
-
assert_equal "Unknown severity message\n", $stderr.string
|
118
|
-
end
|
119
|
-
end
|