markdown_exec 3.2.0 → 3.3.0
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/CHANGELOG.md +27 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +3 -3
- data/bats/block-type-ux-auto.bats +1 -1
- data/bats/block-type-ux-default.bats +1 -1
- data/bats/block-type-ux-echo-hash-transform.bats +1 -1
- data/bats/block-type-ux-echo-hash.bats +2 -2
- data/bats/block-type-ux-exec-hash-transform.bats +8 -0
- data/bats/block-type-ux-exec-hash.bats +15 -0
- data/bats/block-type-ux-exec.bats +1 -1
- data/bats/block-type-ux-force.bats +9 -0
- data/bats/block-type-ux-formats.bats +8 -0
- data/bats/block-type-ux-readonly.bats +1 -1
- data/bats/block-type-ux-row-format.bats +1 -1
- data/bats/block-type-ux-transform.bats +1 -1
- data/bats/import-directive-parameter-symbols.bats +9 -0
- data/bats/import-duplicates.bats +4 -2
- data/bats/import-parameter-symbols.bats +8 -0
- data/bats/markup.bats +1 -1
- data/bats/options.bats +1 -1
- data/bin/tab_completion.sh +5 -1
- data/docs/dev/block-type-ux-echo-hash-transform.md +14 -12
- data/docs/dev/block-type-ux-exec-hash-transform.md +37 -0
- data/docs/dev/block-type-ux-exec-hash.md +93 -0
- data/docs/dev/block-type-ux-force.md +20 -0
- data/docs/dev/block-type-ux-formats.md +58 -0
- data/docs/dev/hexdump_format.md +267 -0
- data/docs/dev/import/parameter-symbols.md +6 -0
- data/docs/dev/import-directive-parameter-symbols.md +9 -0
- data/docs/dev/import-parameter-symbols-template.md +24 -0
- data/docs/dev/import-parameter-symbols.md +6 -0
- data/docs/dev/load-vars-state-demo.md +35 -0
- data/docs/ux-blocks-examples.md +2 -3
- data/examples/import_with_substitution_demo.md +130 -26
- data/examples/imports/organism_template.md +86 -29
- data/lib/cached_nested_file_reader.rb +265 -27
- data/lib/constants.rb +8 -1
- data/lib/env_interface.rb +13 -7
- data/lib/evaluate_shell_expressions.rb +1 -0
- data/lib/fcb.rb +120 -28
- data/lib/format_table.rb +56 -23
- data/lib/fout.rb +5 -0
- data/lib/hash_delegator.rb +1158 -347
- data/lib/markdown_exec/version.rb +1 -1
- data/lib/markdown_exec.rb +2 -0
- data/lib/mdoc.rb +13 -11
- data/lib/menu.src.yml +139 -34
- data/lib/menu.yml +116 -32
- data/lib/string_util.rb +80 -0
- data/lib/table_extractor.rb +170 -64
- data/lib/ww.rb +325 -29
- metadata +18 -2
data/lib/fcb.rb
CHANGED
@@ -25,7 +25,7 @@ def parse_yaml_of_ux_block(
|
|
25
25
|
exec: export['exec'],
|
26
26
|
force: export['force'],
|
27
27
|
init: export['init'],
|
28
|
-
menu_format: export['format'] || export['menu_format'] || menu_format
|
28
|
+
menu_format: export['format'] || export['menu_format'], # || menu_format,####
|
29
29
|
name: name,
|
30
30
|
prompt: export['prompt'] || prompt,
|
31
31
|
readonly: export['readonly'].nil? ? false : export['readonly'],
|
@@ -75,14 +75,6 @@ module MarkdownExec
|
|
75
75
|
full&.to_s&.pub_name(**kwargs)
|
76
76
|
end
|
77
77
|
|
78
|
-
def body
|
79
|
-
@attrs[:body]
|
80
|
-
end
|
81
|
-
|
82
|
-
def body=(value)
|
83
|
-
@attrs[:body] = value
|
84
|
-
end
|
85
|
-
|
86
78
|
def code_name_included?(*names)
|
87
79
|
names.include?(@attrs[:oname])
|
88
80
|
end
|
@@ -101,7 +93,6 @@ module MarkdownExec
|
|
101
93
|
# 2024-08-04 match nickname
|
102
94
|
# may not exist if block name is duplicated
|
103
95
|
def delete_matching_name!(dependencies)
|
104
|
-
####
|
105
96
|
dependencies.delete(@attrs[:id]) ||
|
106
97
|
dependencies.delete(@attrs[:dname]) ||
|
107
98
|
dependencies.delete(@attrs[:nickname]) ||
|
@@ -137,6 +128,7 @@ module MarkdownExec
|
|
137
128
|
# @return [Object] The modified functional code block with updated
|
138
129
|
# summary attributes.
|
139
130
|
def for_menu!(
|
131
|
+
appopts:,
|
140
132
|
block_calls_scan:,
|
141
133
|
block_name_match:,
|
142
134
|
block_name_nick_match:,
|
@@ -172,12 +164,19 @@ module MarkdownExec
|
|
172
164
|
when Hash
|
173
165
|
export = parse_yaml_of_ux_block(
|
174
166
|
data,
|
175
|
-
menu_format: menu_format,
|
176
167
|
prompt: prompt
|
177
168
|
)
|
178
169
|
|
170
|
+
if !export.menu_format || export.menu_format.empty?
|
171
|
+
format_symbol = option_to_format_ux_block(export)
|
172
|
+
export.menu_format = appopts[format_symbol]
|
173
|
+
if !export.menu_format || export.menu_format.empty?
|
174
|
+
export.menu_format = appopts[:menu_ux_row_format]
|
175
|
+
end
|
176
|
+
end
|
177
|
+
@attrs[:oname] = oname = format(export.menu_format, export.to_h)
|
178
|
+
|
179
179
|
@attrs[:center] = table_center
|
180
|
-
oname = @attrs[:oname] = format(export.menu_format, export.to_h)
|
181
180
|
@attrs[:readonly] = export.readonly
|
182
181
|
else
|
183
182
|
# triggered by an empty or non-YAML block
|
@@ -190,7 +189,8 @@ module MarkdownExec
|
|
190
189
|
end
|
191
190
|
|
192
191
|
@attrs[:dname] = HashDelegator.indent_all_lines(
|
193
|
-
|
192
|
+
# yield the text and option name for the color
|
193
|
+
(yield oname, option_to_decorate_ux_block),
|
194
194
|
@attrs[:indent]
|
195
195
|
)
|
196
196
|
|
@@ -208,6 +208,38 @@ module MarkdownExec
|
|
208
208
|
end.join("\n")
|
209
209
|
end
|
210
210
|
|
211
|
+
def self.is_allow?(export)
|
212
|
+
export&.allow&.present?
|
213
|
+
end
|
214
|
+
|
215
|
+
def is_allow?
|
216
|
+
FCB.is_allow?(export)
|
217
|
+
end
|
218
|
+
|
219
|
+
def self.is_echo?(export)
|
220
|
+
export&.echo&.present?
|
221
|
+
end
|
222
|
+
|
223
|
+
def is_echo?
|
224
|
+
FCB.is_echo?(export)
|
225
|
+
end
|
226
|
+
|
227
|
+
def self.is_edit?(export)
|
228
|
+
export&.edit&.present?
|
229
|
+
end
|
230
|
+
|
231
|
+
def is_edit?
|
232
|
+
FCB.is_edit?(export)
|
233
|
+
end
|
234
|
+
|
235
|
+
def self.is_exec?(export)
|
236
|
+
export&.exec&.present?
|
237
|
+
end
|
238
|
+
|
239
|
+
def is_exec?
|
240
|
+
FCB.is_exec?(export)
|
241
|
+
end
|
242
|
+
|
211
243
|
def self.act_source(export)
|
212
244
|
# If `false`, the UX block is not activated.
|
213
245
|
# If one of `:allow`, `:echo`, `:edit`, or `:exec` is specified,
|
@@ -215,18 +247,22 @@ module MarkdownExec
|
|
215
247
|
# If not present, the default value is `:edit`.
|
216
248
|
if export.act.nil?
|
217
249
|
export.act = if export.init.to_s == 'false'
|
218
|
-
if export.allow.present?
|
250
|
+
# if export.allow.present?
|
251
|
+
if FCB.is_allow?(export)
|
219
252
|
UxActSource::ALLOW
|
220
|
-
elsif export.echo.present?
|
253
|
+
# elsif export.echo.present?
|
254
|
+
elsif FCB.is_echo?(export)
|
221
255
|
UxActSource::ECHO
|
222
|
-
elsif export.edit.present?
|
256
|
+
# elsif export.edit.present?
|
257
|
+
elsif FCB.is_edit?(export)
|
223
258
|
UxActSource::EDIT
|
224
|
-
elsif export.exec.present?
|
259
|
+
# elsif export.exec.present?
|
260
|
+
elsif FCB.is_exec?(export)
|
225
261
|
UxActSource::EXEC
|
226
262
|
else
|
227
263
|
UxActSource::EDIT
|
228
264
|
end
|
229
|
-
elsif
|
265
|
+
elsif FCB.is_allow?(export)
|
230
266
|
UxActSource::ALLOW
|
231
267
|
else
|
232
268
|
UxActSource::EDIT
|
@@ -246,13 +282,15 @@ module MarkdownExec
|
|
246
282
|
# `:allow`, `:default`, `:echo`, or `:exec` is present.
|
247
283
|
if export.init.nil?
|
248
284
|
export.init = case
|
249
|
-
when
|
285
|
+
when FCB.is_allow?(export)
|
250
286
|
UxActSource::ALLOW
|
251
287
|
when export.default.present?
|
252
288
|
UxActSource::DEFAULT
|
253
|
-
when export.echo.present?
|
289
|
+
# when export.echo.present?
|
290
|
+
when FCB.is_echo?(export)
|
254
291
|
UxActSource::ECHO
|
255
|
-
when export.exec.present?
|
292
|
+
# when export.exec.present?
|
293
|
+
when FCB.is_exec?(export)
|
256
294
|
UxActSource::EXEC
|
257
295
|
else
|
258
296
|
UxActSource::FALSE
|
@@ -265,7 +303,8 @@ module MarkdownExec
|
|
265
303
|
# :reek:ManualDispatch
|
266
304
|
# 2024-08-04 match nickname
|
267
305
|
def is_dependency_of?(dependency_names)
|
268
|
-
dependency_names.include?(@attrs[:
|
306
|
+
dependency_names.include?(@attrs[:id]) ||
|
307
|
+
dependency_names.include?(@attrs[:dname]) ||
|
269
308
|
dependency_names.include?(@attrs[:nickname]) ||
|
270
309
|
dependency_names.include?(@attrs[:oname]) ||
|
271
310
|
dependency_names.include?(@attrs.pub_name) ||
|
@@ -281,12 +320,16 @@ module MarkdownExec
|
|
281
320
|
end
|
282
321
|
|
283
322
|
def is_named?(name)
|
284
|
-
|
285
|
-
@attrs[:
|
286
|
-
|
287
|
-
@attrs[:
|
288
|
-
|
289
|
-
|
323
|
+
if /^ItrBlk/.match(name)
|
324
|
+
@attrs[:id] == name
|
325
|
+
else
|
326
|
+
@attrs[:id] == name ||
|
327
|
+
@attrs[:dname] == name ||
|
328
|
+
@attrs[:nickname] == name ||
|
329
|
+
@attrs[:oname] == name ||
|
330
|
+
@attrs.pub_name == name ||
|
331
|
+
@attrs[:s2title] == name
|
332
|
+
end
|
290
333
|
end
|
291
334
|
|
292
335
|
# true if this is a line split block
|
@@ -343,6 +386,54 @@ module MarkdownExec
|
|
343
386
|
end
|
344
387
|
end
|
345
388
|
|
389
|
+
# calc the decoration sybol for the current block
|
390
|
+
def option_to_decorate_ux_block
|
391
|
+
symbol_or_hash = BLOCK_TYPE_COLOR_OPTIONS[@attrs[:type]]
|
392
|
+
if @attrs[:type] == BlockType::UX
|
393
|
+
# only UX blocks accept a symbol or a hash
|
394
|
+
if symbol_or_hash.is_a? Hash
|
395
|
+
# default to the first symbol
|
396
|
+
symbol = symbol_or_hash.first.last
|
397
|
+
symbol_or_hash.keys.each do |key|
|
398
|
+
if key == true
|
399
|
+
symbol = symbol_or_hash[key]
|
400
|
+
break
|
401
|
+
elsif symbol_or_hash[key].present? && send(key)
|
402
|
+
symbol = symbol_or_hash[key]
|
403
|
+
break
|
404
|
+
end
|
405
|
+
end
|
406
|
+
symbol
|
407
|
+
else
|
408
|
+
# only symbol
|
409
|
+
symbol_or_hash
|
410
|
+
end
|
411
|
+
else
|
412
|
+
# only symbol
|
413
|
+
symbol_or_hash
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
def option_to_format_ux_block(export)
|
418
|
+
if export.readonly
|
419
|
+
:menu_ux_row_format_readonly
|
420
|
+
else
|
421
|
+
case FCB.act_source(export)
|
422
|
+
when UxActSource::ALLOW
|
423
|
+
:menu_ux_row_format_allow
|
424
|
+
when UxActSource::ECHO
|
425
|
+
:menu_ux_row_format_echo
|
426
|
+
when UxActSource::EDIT
|
427
|
+
:menu_ux_row_format_edit
|
428
|
+
when UxActSource::EXEC
|
429
|
+
:menu_ux_row_format_exec
|
430
|
+
else
|
431
|
+
# this UX block does not have a format, treat as editable
|
432
|
+
:menu_ux_row_format_edit
|
433
|
+
end
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
346
437
|
def respond_to_missing?(method_name, include_private = false)
|
347
438
|
@attrs.key?(method_name.to_sym) || super
|
348
439
|
end
|
@@ -392,6 +483,7 @@ module MarkdownExec
|
|
392
483
|
# Replace variables in each line of `body` if `body` is present
|
393
484
|
return unless @attrs[:body]
|
394
485
|
|
486
|
+
# save body for YAML and re-interpretation
|
395
487
|
@attrs[:raw_body] ||= @attrs[:body]
|
396
488
|
@attrs[:body] = @attrs[:body]&.map do |line|
|
397
489
|
if line.empty?
|
data/lib/format_table.rb
CHANGED
@@ -141,7 +141,10 @@ module MarkdownTableFormatter
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def format_table__hs(
|
144
|
-
|
144
|
+
column_count:,
|
145
|
+
lines:,
|
146
|
+
table:,
|
147
|
+
decorate: nil,
|
145
148
|
table_width: nil,
|
146
149
|
truncate: true
|
147
150
|
)
|
@@ -152,7 +155,9 @@ module MarkdownTableFormatter
|
|
152
155
|
end
|
153
156
|
end
|
154
157
|
|
155
|
-
rows = raw_lines_into_row_role_cells(
|
158
|
+
rows = raw_lines_into_row_role_cells(
|
159
|
+
lines, column_count, delimiter: table[:delimiter]
|
160
|
+
)
|
156
161
|
|
157
162
|
alignment_indicators, column_widths =
|
158
163
|
calculate_column_alignment_and_widths(rows, column_count)
|
@@ -182,18 +187,22 @@ module MarkdownTableFormatter
|
|
182
187
|
result
|
183
188
|
end
|
184
189
|
|
185
|
-
def raw_lines_into_row_role_cells(
|
190
|
+
def raw_lines_into_row_role_cells(
|
191
|
+
lines, column_count, delimiter:
|
192
|
+
)
|
186
193
|
role = :header_row
|
187
194
|
counter = -1
|
188
195
|
|
189
196
|
ret = []
|
190
197
|
lines.each do |line|
|
191
|
-
line +=
|
198
|
+
line += delimiter unless line.end_with?(delimiter)
|
199
|
+
|
192
200
|
counter += 1
|
193
201
|
|
194
202
|
role = role_for_raw_row(role, line)
|
195
203
|
counter = reset_counter_if_needed(role, counter)
|
196
|
-
cells = split_decorated_row_into_cells(line, column_count
|
204
|
+
cells = split_decorated_row_into_cells(line, column_count,
|
205
|
+
delimiter: delimiter)
|
197
206
|
ret << OpenStruct.new(cells: cells, role: role, counter: counter)
|
198
207
|
end
|
199
208
|
ret
|
@@ -220,8 +229,8 @@ module MarkdownTableFormatter
|
|
220
229
|
end
|
221
230
|
end
|
222
231
|
|
223
|
-
def split_decorated_row_into_cells(line, column_count)
|
224
|
-
cells = line.split(
|
232
|
+
def split_decorated_row_into_cells(line, column_count, delimiter: '|')
|
233
|
+
cells = line.split(delimiter).map(&:strip)[1..-1]
|
225
234
|
cells&.slice(0, column_count)&.fill('', cells.length...column_count)
|
226
235
|
end
|
227
236
|
end
|
@@ -239,11 +248,12 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
239
248
|
'| Row 2 Col 1 | Row 2 Col 2 | Row 2 Col 3 |'
|
240
249
|
]
|
241
250
|
@column_count = 3
|
251
|
+
@table = { delimiter: '|' }
|
242
252
|
end
|
243
253
|
|
244
254
|
def test_format_table
|
245
255
|
result = MarkdownTableFormatter.format_table(
|
246
|
-
column_count: @column_count, lines: @lines
|
256
|
+
column_count: @column_count, lines: @lines, table: @table
|
247
257
|
)
|
248
258
|
expected = [
|
249
259
|
'| Header 1 | Header 2 | Header 3 |',
|
@@ -259,7 +269,8 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
259
269
|
result = MarkdownTableFormatter.format_table(
|
260
270
|
column_count: @column_count,
|
261
271
|
decorate: decorate,
|
262
|
-
lines: @lines
|
272
|
+
lines: @lines,
|
273
|
+
table: @table
|
263
274
|
)
|
264
275
|
expected = [
|
265
276
|
'| HEADER 1 | HEADER 2 | HEADER 3 |',
|
@@ -280,7 +291,8 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
280
291
|
]
|
281
292
|
result = MarkdownTableFormatter.format_table(
|
282
293
|
lines: lines_with_empty,
|
283
|
-
column_count: @column_count
|
294
|
+
column_count: @column_count,
|
295
|
+
table: @table
|
284
296
|
)
|
285
297
|
expected = [
|
286
298
|
'| Header 1 | Header 2 | Header 3 |',
|
@@ -299,7 +311,8 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
299
311
|
]
|
300
312
|
result = MarkdownTableFormatter.format_table(
|
301
313
|
lines: lines_with_alignment,
|
302
|
-
column_count: @column_count
|
314
|
+
column_count: @column_count,
|
315
|
+
table: @table
|
303
316
|
)
|
304
317
|
expected = [
|
305
318
|
'| Header 1 | Header 2 | Header 3 |',
|
@@ -310,6 +323,10 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
310
323
|
end
|
311
324
|
|
312
325
|
class TestFormatTable < Minitest::Test
|
326
|
+
def setup
|
327
|
+
@table = { delimiter: '|' }
|
328
|
+
end
|
329
|
+
|
313
330
|
def test_basic_formatting
|
314
331
|
lines = [
|
315
332
|
'| Species| Genus| Family',
|
@@ -326,7 +343,8 @@ class TestFormatTable < Minitest::Test
|
|
326
343
|
]
|
327
344
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
328
345
|
lines: lines,
|
329
|
-
column_count: column_count
|
346
|
+
column_count: column_count,
|
347
|
+
table: @table
|
330
348
|
)
|
331
349
|
end
|
332
350
|
|
@@ -344,7 +362,8 @@ class TestFormatTable < Minitest::Test
|
|
344
362
|
]
|
345
363
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
346
364
|
lines: lines,
|
347
|
-
column_count: column_count
|
365
|
+
column_count: column_count,
|
366
|
+
table: @table
|
348
367
|
)
|
349
368
|
end
|
350
369
|
|
@@ -364,7 +383,8 @@ class TestFormatTable < Minitest::Test
|
|
364
383
|
def test_empty_input
|
365
384
|
assert_equal [], MarkdownTableFormatter.format_table(
|
366
385
|
lines: [],
|
367
|
-
column_count: 3
|
386
|
+
column_count: 3,
|
387
|
+
table: @table
|
368
388
|
)
|
369
389
|
end
|
370
390
|
|
@@ -382,7 +402,8 @@ class TestFormatTable < Minitest::Test
|
|
382
402
|
]
|
383
403
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
384
404
|
lines: lines,
|
385
|
-
column_count: column_count
|
405
|
+
column_count: column_count,
|
406
|
+
table: @table
|
386
407
|
)
|
387
408
|
end
|
388
409
|
|
@@ -398,12 +419,17 @@ class TestFormatTable < Minitest::Test
|
|
398
419
|
]
|
399
420
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
400
421
|
lines: lines,
|
401
|
-
column_count: column_count
|
422
|
+
column_count: column_count,
|
423
|
+
table: @table
|
402
424
|
)
|
403
425
|
end
|
404
426
|
end
|
405
427
|
|
406
428
|
class TestFormatTable2 < Minitest::Test
|
429
|
+
def setup
|
430
|
+
@table = { delimiter: '|' }
|
431
|
+
end
|
432
|
+
|
407
433
|
def test_basic_formatting
|
408
434
|
lines = [
|
409
435
|
'| Name | Age | City |',
|
@@ -417,7 +443,8 @@ class TestFormatTable2 < Minitest::Test
|
|
417
443
|
]
|
418
444
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
419
445
|
lines: lines,
|
420
|
-
column_count: 3
|
446
|
+
column_count: 3,
|
447
|
+
table: @table
|
421
448
|
)
|
422
449
|
end
|
423
450
|
|
@@ -434,7 +461,8 @@ class TestFormatTable2 < Minitest::Test
|
|
434
461
|
]
|
435
462
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
436
463
|
lines: lines,
|
437
|
-
column_count: 3
|
464
|
+
column_count: 3,
|
465
|
+
table: @table
|
438
466
|
)
|
439
467
|
end
|
440
468
|
|
@@ -451,7 +479,8 @@ class TestFormatTable2 < Minitest::Test
|
|
451
479
|
]
|
452
480
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
453
481
|
lines: lines,
|
454
|
-
column_count: 4
|
482
|
+
column_count: 4,
|
483
|
+
table: @table
|
455
484
|
)
|
456
485
|
end
|
457
486
|
|
@@ -468,7 +497,8 @@ class TestFormatTable2 < Minitest::Test
|
|
468
497
|
]
|
469
498
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
470
499
|
lines: lines,
|
471
|
-
column_count: 3
|
500
|
+
column_count: 3,
|
501
|
+
table: @table
|
472
502
|
)
|
473
503
|
end
|
474
504
|
|
@@ -477,7 +507,8 @@ class TestFormatTable2 < Minitest::Test
|
|
477
507
|
expected_output = ['| Name | Age | City |']
|
478
508
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
479
509
|
lines: lines,
|
480
|
-
column_count: 3
|
510
|
+
column_count: 3,
|
511
|
+
table: @table
|
481
512
|
)
|
482
513
|
end
|
483
514
|
|
@@ -486,7 +517,8 @@ class TestFormatTable2 < Minitest::Test
|
|
486
517
|
expected_output = []
|
487
518
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
488
519
|
lines: lines,
|
489
|
-
column_count: 3
|
520
|
+
column_count: 3,
|
521
|
+
table: @table
|
490
522
|
)
|
491
523
|
end
|
492
524
|
|
@@ -501,7 +533,8 @@ class TestFormatTable2 < Minitest::Test
|
|
501
533
|
]
|
502
534
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
503
535
|
lines: lines,
|
504
|
-
column_count: 3
|
536
|
+
column_count: 3,
|
537
|
+
table: @table
|
505
538
|
)
|
506
539
|
end
|
507
540
|
end
|
data/lib/fout.rb
CHANGED
@@ -33,6 +33,11 @@ class FOut
|
|
33
33
|
puts str
|
34
34
|
end
|
35
35
|
|
36
|
+
# `puts` guarantees exactly one line break per item it prints. For each
|
37
|
+
# argument (and for each element when given an Array), it appends a newline
|
38
|
+
# only if the string does not already end with "\n". If it does, `puts`
|
39
|
+
# does not add another. Net effect: trailing newlines in your data are
|
40
|
+
# consumed rather than duplicated, so "Line\n" does not create a blank line.
|
36
41
|
def fout_list(str)
|
37
42
|
puts str
|
38
43
|
end
|