markdown_exec 3.2.0 → 3.4.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 +40 -0
- data/Gemfile.lock +1 -1
- data/Rakefile +5 -4
- data/bats/block-type-ux-echo-hash-transform.bats +1 -1
- 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-force.bats +9 -0
- data/bats/block-type-ux-formats.bats +8 -0
- data/bats/block-type-ux-no-name.bats +8 -0
- data/bats/block-type-ux-readonly.bats +1 -1
- data/bats/block-type-ux-row-format.bats +1 -1
- data/bats/command-substitution-options.bats +2 -2
- data/bats/import-directive-line-continuation.bats +9 -0
- 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/option-expansion.bats +1 -1
- data/bats/options.bats +1 -1
- data/bats/table-column-truncate.bats +1 -1
- data/bats/table.bats +1 -1
- data/bats/test_helper.bash +4 -3
- 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/block-type-ux-no-name.md +17 -0
- data/docs/dev/block-type-ux-row-format.md +1 -1
- data/docs/dev/hexdump_format.md +267 -0
- data/docs/dev/import/parameter-symbols.md +6 -0
- data/docs/dev/import-directive-line-continuation.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/dev/table-column-truncate.md +1 -1
- 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 +279 -29
- 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 +133 -33
- data/lib/format_table.rb +77 -29
- data/lib/fout.rb +5 -0
- data/lib/hash_delegator.rb +1159 -348
- 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 +166 -62
- data/lib/menu.yml +143 -59
- data/lib/string_util.rb +80 -0
- data/lib/table_extractor.rb +170 -64
- data/lib/ww.rb +810 -36
- metadata +22 -2
data/lib/fcb.rb
CHANGED
@@ -7,15 +7,23 @@ require_relative 'namer'
|
|
7
7
|
BT_UX_FLD_REQUIRED = 'required'
|
8
8
|
def parse_yaml_of_ux_block(
|
9
9
|
data,
|
10
|
-
menu_format: nil,
|
11
10
|
prompt: nil,
|
12
11
|
validate: nil
|
13
12
|
)
|
14
|
-
export = data['export']
|
15
|
-
export = data if export.nil?
|
16
|
-
name = export['name']
|
13
|
+
export = data if (export = data['export']).nil?
|
17
14
|
|
18
|
-
|
15
|
+
# a single variable name is required to display a single value
|
16
|
+
menu_format = export['format'] || export['menu_format']
|
17
|
+
name = export['name']
|
18
|
+
# if name is missing, use the last key in the echo or exec hashes
|
19
|
+
if !name&.present?
|
20
|
+
name = if export['echo'].is_a? Hash
|
21
|
+
export['echo'].keys.last
|
22
|
+
elsif export['exec'].is_a? Hash
|
23
|
+
export['exec'].keys.last
|
24
|
+
end
|
25
|
+
end
|
26
|
+
raise "Name is missing in UX block: #{data.inspect}" unless name.present? || menu_format.present?
|
19
27
|
|
20
28
|
OpenStruct.new(
|
21
29
|
act: export['act'],
|
@@ -25,7 +33,7 @@ def parse_yaml_of_ux_block(
|
|
25
33
|
exec: export['exec'],
|
26
34
|
force: export['force'],
|
27
35
|
init: export['init'],
|
28
|
-
menu_format:
|
36
|
+
menu_format: menu_format,
|
29
37
|
name: name,
|
30
38
|
prompt: export['prompt'] || prompt,
|
31
39
|
readonly: export['readonly'].nil? ? false : export['readonly'],
|
@@ -75,14 +83,6 @@ module MarkdownExec
|
|
75
83
|
full&.to_s&.pub_name(**kwargs)
|
76
84
|
end
|
77
85
|
|
78
|
-
def body
|
79
|
-
@attrs[:body]
|
80
|
-
end
|
81
|
-
|
82
|
-
def body=(value)
|
83
|
-
@attrs[:body] = value
|
84
|
-
end
|
85
|
-
|
86
86
|
def code_name_included?(*names)
|
87
87
|
names.include?(@attrs[:oname])
|
88
88
|
end
|
@@ -101,7 +101,6 @@ module MarkdownExec
|
|
101
101
|
# 2024-08-04 match nickname
|
102
102
|
# may not exist if block name is duplicated
|
103
103
|
def delete_matching_name!(dependencies)
|
104
|
-
####
|
105
104
|
dependencies.delete(@attrs[:id]) ||
|
106
105
|
dependencies.delete(@attrs[:dname]) ||
|
107
106
|
dependencies.delete(@attrs[:nickname]) ||
|
@@ -137,6 +136,7 @@ module MarkdownExec
|
|
137
136
|
# @return [Object] The modified functional code block with updated
|
138
137
|
# summary attributes.
|
139
138
|
def for_menu!(
|
139
|
+
appopts:,
|
140
140
|
block_calls_scan:,
|
141
141
|
block_name_match:,
|
142
142
|
block_name_nick_match:,
|
@@ -172,12 +172,19 @@ module MarkdownExec
|
|
172
172
|
when Hash
|
173
173
|
export = parse_yaml_of_ux_block(
|
174
174
|
data,
|
175
|
-
menu_format: menu_format,
|
176
175
|
prompt: prompt
|
177
176
|
)
|
178
177
|
|
178
|
+
if !export.menu_format || export.menu_format.empty?
|
179
|
+
format_symbol = option_to_format_ux_block(export)
|
180
|
+
export.menu_format = appopts[format_symbol]
|
181
|
+
if !export.menu_format || export.menu_format.empty?
|
182
|
+
export.menu_format = appopts[:menu_ux_row_format]
|
183
|
+
end
|
184
|
+
end
|
185
|
+
@attrs[:oname] = oname = format(export.menu_format, export.to_h)
|
186
|
+
|
179
187
|
@attrs[:center] = table_center
|
180
|
-
oname = @attrs[:oname] = format(export.menu_format, export.to_h)
|
181
188
|
@attrs[:readonly] = export.readonly
|
182
189
|
else
|
183
190
|
# triggered by an empty or non-YAML block
|
@@ -190,7 +197,8 @@ module MarkdownExec
|
|
190
197
|
end
|
191
198
|
|
192
199
|
@attrs[:dname] = HashDelegator.indent_all_lines(
|
193
|
-
|
200
|
+
# yield the text and option name for the color
|
201
|
+
(yield oname, option_to_decorate_ux_block),
|
194
202
|
@attrs[:indent]
|
195
203
|
)
|
196
204
|
|
@@ -208,6 +216,38 @@ module MarkdownExec
|
|
208
216
|
end.join("\n")
|
209
217
|
end
|
210
218
|
|
219
|
+
def self.is_allow?(export)
|
220
|
+
export&.allow&.present?
|
221
|
+
end
|
222
|
+
|
223
|
+
def is_allow?
|
224
|
+
FCB.is_allow?(export)
|
225
|
+
end
|
226
|
+
|
227
|
+
def self.is_echo?(export)
|
228
|
+
export&.echo&.present?
|
229
|
+
end
|
230
|
+
|
231
|
+
def is_echo?
|
232
|
+
FCB.is_echo?(export)
|
233
|
+
end
|
234
|
+
|
235
|
+
def self.is_edit?(export)
|
236
|
+
export&.edit&.present?
|
237
|
+
end
|
238
|
+
|
239
|
+
def is_edit?
|
240
|
+
FCB.is_edit?(export)
|
241
|
+
end
|
242
|
+
|
243
|
+
def self.is_exec?(export)
|
244
|
+
export&.exec&.present?
|
245
|
+
end
|
246
|
+
|
247
|
+
def is_exec?
|
248
|
+
FCB.is_exec?(export)
|
249
|
+
end
|
250
|
+
|
211
251
|
def self.act_source(export)
|
212
252
|
# If `false`, the UX block is not activated.
|
213
253
|
# If one of `:allow`, `:echo`, `:edit`, or `:exec` is specified,
|
@@ -215,18 +255,22 @@ module MarkdownExec
|
|
215
255
|
# If not present, the default value is `:edit`.
|
216
256
|
if export.act.nil?
|
217
257
|
export.act = if export.init.to_s == 'false'
|
218
|
-
if export.allow.present?
|
258
|
+
# if export.allow.present?
|
259
|
+
if FCB.is_allow?(export)
|
219
260
|
UxActSource::ALLOW
|
220
|
-
elsif export.echo.present?
|
261
|
+
# elsif export.echo.present?
|
262
|
+
elsif FCB.is_echo?(export)
|
221
263
|
UxActSource::ECHO
|
222
|
-
elsif export.edit.present?
|
264
|
+
# elsif export.edit.present?
|
265
|
+
elsif FCB.is_edit?(export)
|
223
266
|
UxActSource::EDIT
|
224
|
-
elsif export.exec.present?
|
267
|
+
# elsif export.exec.present?
|
268
|
+
elsif FCB.is_exec?(export)
|
225
269
|
UxActSource::EXEC
|
226
270
|
else
|
227
271
|
UxActSource::EDIT
|
228
272
|
end
|
229
|
-
elsif
|
273
|
+
elsif FCB.is_allow?(export)
|
230
274
|
UxActSource::ALLOW
|
231
275
|
else
|
232
276
|
UxActSource::EDIT
|
@@ -246,13 +290,15 @@ module MarkdownExec
|
|
246
290
|
# `:allow`, `:default`, `:echo`, or `:exec` is present.
|
247
291
|
if export.init.nil?
|
248
292
|
export.init = case
|
249
|
-
when
|
293
|
+
when FCB.is_allow?(export)
|
250
294
|
UxActSource::ALLOW
|
251
295
|
when export.default.present?
|
252
296
|
UxActSource::DEFAULT
|
253
|
-
when export.echo.present?
|
297
|
+
# when export.echo.present?
|
298
|
+
when FCB.is_echo?(export)
|
254
299
|
UxActSource::ECHO
|
255
|
-
when export.exec.present?
|
300
|
+
# when export.exec.present?
|
301
|
+
when FCB.is_exec?(export)
|
256
302
|
UxActSource::EXEC
|
257
303
|
else
|
258
304
|
UxActSource::FALSE
|
@@ -265,7 +311,8 @@ module MarkdownExec
|
|
265
311
|
# :reek:ManualDispatch
|
266
312
|
# 2024-08-04 match nickname
|
267
313
|
def is_dependency_of?(dependency_names)
|
268
|
-
dependency_names.include?(@attrs[:
|
314
|
+
dependency_names.include?(@attrs[:id]) ||
|
315
|
+
dependency_names.include?(@attrs[:dname]) ||
|
269
316
|
dependency_names.include?(@attrs[:nickname]) ||
|
270
317
|
dependency_names.include?(@attrs[:oname]) ||
|
271
318
|
dependency_names.include?(@attrs.pub_name) ||
|
@@ -281,12 +328,16 @@ module MarkdownExec
|
|
281
328
|
end
|
282
329
|
|
283
330
|
def is_named?(name)
|
284
|
-
|
285
|
-
@attrs[:
|
286
|
-
|
287
|
-
@attrs[:
|
288
|
-
|
289
|
-
|
331
|
+
if /^ItrBlk/.match(name)
|
332
|
+
@attrs[:id] == name
|
333
|
+
else
|
334
|
+
@attrs[:id] == name ||
|
335
|
+
@attrs[:dname] == name ||
|
336
|
+
@attrs[:nickname] == name ||
|
337
|
+
@attrs[:oname] == name ||
|
338
|
+
@attrs.pub_name == name ||
|
339
|
+
@attrs[:s2title] == name
|
340
|
+
end
|
290
341
|
end
|
291
342
|
|
292
343
|
# true if this is a line split block
|
@@ -343,6 +394,54 @@ module MarkdownExec
|
|
343
394
|
end
|
344
395
|
end
|
345
396
|
|
397
|
+
# calc the decoration sybol for the current block
|
398
|
+
def option_to_decorate_ux_block
|
399
|
+
symbol_or_hash = BLOCK_TYPE_COLOR_OPTIONS[@attrs[:type]]
|
400
|
+
if @attrs[:type] == BlockType::UX
|
401
|
+
# only UX blocks accept a symbol or a hash
|
402
|
+
if symbol_or_hash.is_a? Hash
|
403
|
+
# default to the first symbol
|
404
|
+
symbol = symbol_or_hash.first.last
|
405
|
+
symbol_or_hash.each_key do |key|
|
406
|
+
if key == true
|
407
|
+
symbol = symbol_or_hash[key]
|
408
|
+
break
|
409
|
+
elsif symbol_or_hash[key].present? && send(key)
|
410
|
+
symbol = symbol_or_hash[key]
|
411
|
+
break
|
412
|
+
end
|
413
|
+
end
|
414
|
+
symbol
|
415
|
+
else
|
416
|
+
# only symbol
|
417
|
+
symbol_or_hash
|
418
|
+
end
|
419
|
+
else
|
420
|
+
# only symbol
|
421
|
+
symbol_or_hash
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
def option_to_format_ux_block(export)
|
426
|
+
if export.readonly
|
427
|
+
:menu_ux_row_format_readonly
|
428
|
+
else
|
429
|
+
case FCB.act_source(export)
|
430
|
+
when UxActSource::ALLOW
|
431
|
+
:menu_ux_row_format_allow
|
432
|
+
when UxActSource::ECHO
|
433
|
+
:menu_ux_row_format_echo
|
434
|
+
when UxActSource::EDIT
|
435
|
+
:menu_ux_row_format_edit
|
436
|
+
when UxActSource::EXEC
|
437
|
+
:menu_ux_row_format_exec
|
438
|
+
else
|
439
|
+
# this UX block does not have a format, treat as editable
|
440
|
+
:menu_ux_row_format_edit
|
441
|
+
end
|
442
|
+
end
|
443
|
+
end
|
444
|
+
|
346
445
|
def respond_to_missing?(method_name, include_private = false)
|
347
446
|
@attrs.key?(method_name.to_sym) || super
|
348
447
|
end
|
@@ -392,6 +491,7 @@ module MarkdownExec
|
|
392
491
|
# Replace variables in each line of `body` if `body` is present
|
393
492
|
return unless @attrs[:body]
|
394
493
|
|
494
|
+
# save body for YAML and re-interpretation
|
395
495
|
@attrs[:raw_body] ||= @attrs[:body]
|
396
496
|
@attrs[:body] = @attrs[:body]&.map do |line|
|
397
497
|
if line.empty?
|
data/lib/format_table.rb
CHANGED
@@ -141,8 +141,11 @@ module MarkdownTableFormatter
|
|
141
141
|
end
|
142
142
|
|
143
143
|
def format_table__hs(
|
144
|
-
|
145
|
-
|
144
|
+
column_count:,
|
145
|
+
decorate: nil,
|
146
|
+
lines:,
|
147
|
+
max_table_width: nil,
|
148
|
+
table:,
|
146
149
|
truncate: true
|
147
150
|
)
|
148
151
|
unless column_count.positive?
|
@@ -152,18 +155,33 @@ 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)
|
159
164
|
|
160
|
-
unless
|
161
|
-
|
162
|
-
|
163
|
-
|
165
|
+
unless max_table_width.nil?
|
166
|
+
# each column has a frame width of 3 characters
|
167
|
+
# border and space before and after each and 1 final border
|
168
|
+
borders_width = (column_count * 3) + 1
|
169
|
+
|
170
|
+
full_column_table_width = column_widths.sum + borders_width
|
171
|
+
|
172
|
+
if full_column_table_width > max_table_width
|
173
|
+
text_width_sum = full_column_table_width - borders_width
|
174
|
+
available_text_width = max_table_width - borders_width
|
175
|
+
ratio = available_text_width.to_f / text_width_sum
|
176
|
+
|
177
|
+
# distribute the width across the columns
|
164
178
|
column_widths.each_with_index do |width, i|
|
165
179
|
column_widths[i] = (width * ratio).to_i
|
166
180
|
end
|
181
|
+
|
182
|
+
# the last column fills the remaining width
|
183
|
+
column_widths[column_widths.count - 1] =
|
184
|
+
available_text_width - column_widths.sum + column_widths.last
|
167
185
|
end
|
168
186
|
end
|
169
187
|
|
@@ -182,18 +200,22 @@ module MarkdownTableFormatter
|
|
182
200
|
result
|
183
201
|
end
|
184
202
|
|
185
|
-
def raw_lines_into_row_role_cells(
|
203
|
+
def raw_lines_into_row_role_cells(
|
204
|
+
lines, column_count, delimiter:
|
205
|
+
)
|
186
206
|
role = :header_row
|
187
207
|
counter = -1
|
188
208
|
|
189
209
|
ret = []
|
190
210
|
lines.each do |line|
|
191
|
-
line +=
|
211
|
+
line += delimiter unless line.end_with?(delimiter)
|
212
|
+
|
192
213
|
counter += 1
|
193
214
|
|
194
215
|
role = role_for_raw_row(role, line)
|
195
216
|
counter = reset_counter_if_needed(role, counter)
|
196
|
-
cells = split_decorated_row_into_cells(line, column_count
|
217
|
+
cells = split_decorated_row_into_cells(line, column_count,
|
218
|
+
delimiter: delimiter)
|
197
219
|
ret << OpenStruct.new(cells: cells, role: role, counter: counter)
|
198
220
|
end
|
199
221
|
ret
|
@@ -220,8 +242,8 @@ module MarkdownTableFormatter
|
|
220
242
|
end
|
221
243
|
end
|
222
244
|
|
223
|
-
def split_decorated_row_into_cells(line, column_count)
|
224
|
-
cells = line.split(
|
245
|
+
def split_decorated_row_into_cells(line, column_count, delimiter: '|')
|
246
|
+
cells = line.split(delimiter).map(&:strip)[1..-1]
|
225
247
|
cells&.slice(0, column_count)&.fill('', cells.length...column_count)
|
226
248
|
end
|
227
249
|
end
|
@@ -229,6 +251,7 @@ end
|
|
229
251
|
return if $PROGRAM_NAME != __FILE__
|
230
252
|
|
231
253
|
require 'minitest/autorun'
|
254
|
+
require_relative 'ww'
|
232
255
|
|
233
256
|
class TestMarkdownTableFormatter < Minitest::Test
|
234
257
|
def setup
|
@@ -239,11 +262,12 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
239
262
|
'| Row 2 Col 1 | Row 2 Col 2 | Row 2 Col 3 |'
|
240
263
|
]
|
241
264
|
@column_count = 3
|
265
|
+
@table = { delimiter: '|' }
|
242
266
|
end
|
243
267
|
|
244
268
|
def test_format_table
|
245
269
|
result = MarkdownTableFormatter.format_table(
|
246
|
-
column_count: @column_count, lines: @lines
|
270
|
+
column_count: @column_count, lines: @lines, table: @table
|
247
271
|
)
|
248
272
|
expected = [
|
249
273
|
'| Header 1 | Header 2 | Header 3 |',
|
@@ -259,7 +283,8 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
259
283
|
result = MarkdownTableFormatter.format_table(
|
260
284
|
column_count: @column_count,
|
261
285
|
decorate: decorate,
|
262
|
-
lines: @lines
|
286
|
+
lines: @lines,
|
287
|
+
table: @table
|
263
288
|
)
|
264
289
|
expected = [
|
265
290
|
'| HEADER 1 | HEADER 2 | HEADER 3 |',
|
@@ -280,7 +305,8 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
280
305
|
]
|
281
306
|
result = MarkdownTableFormatter.format_table(
|
282
307
|
lines: lines_with_empty,
|
283
|
-
column_count: @column_count
|
308
|
+
column_count: @column_count,
|
309
|
+
table: @table
|
284
310
|
)
|
285
311
|
expected = [
|
286
312
|
'| Header 1 | Header 2 | Header 3 |',
|
@@ -299,7 +325,8 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
299
325
|
]
|
300
326
|
result = MarkdownTableFormatter.format_table(
|
301
327
|
lines: lines_with_alignment,
|
302
|
-
column_count: @column_count
|
328
|
+
column_count: @column_count,
|
329
|
+
table: @table
|
303
330
|
)
|
304
331
|
expected = [
|
305
332
|
'| Header 1 | Header 2 | Header 3 |',
|
@@ -310,6 +337,10 @@ class TestMarkdownTableFormatter < Minitest::Test
|
|
310
337
|
end
|
311
338
|
|
312
339
|
class TestFormatTable < Minitest::Test
|
340
|
+
def setup
|
341
|
+
@table = { delimiter: '|' }
|
342
|
+
end
|
343
|
+
|
313
344
|
def test_basic_formatting
|
314
345
|
lines = [
|
315
346
|
'| Species| Genus| Family',
|
@@ -326,7 +357,8 @@ class TestFormatTable < Minitest::Test
|
|
326
357
|
]
|
327
358
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
328
359
|
lines: lines,
|
329
|
-
column_count: column_count
|
360
|
+
column_count: column_count,
|
361
|
+
table: @table
|
330
362
|
)
|
331
363
|
end
|
332
364
|
|
@@ -344,7 +376,8 @@ class TestFormatTable < Minitest::Test
|
|
344
376
|
]
|
345
377
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
346
378
|
lines: lines,
|
347
|
-
column_count: column_count
|
379
|
+
column_count: column_count,
|
380
|
+
table: @table
|
348
381
|
)
|
349
382
|
end
|
350
383
|
|
@@ -358,13 +391,15 @@ class TestFormatTable < Minitest::Test
|
|
358
391
|
# "| A | B | C ",
|
359
392
|
# "| 1 | 2 | 3 "
|
360
393
|
# ]
|
361
|
-
# assert_equal expected,
|
394
|
+
# assert_equal expected,
|
395
|
+
# MarkdownTableFormatter.format_table(lines, column_count)
|
362
396
|
# end
|
363
397
|
|
364
398
|
def test_empty_input
|
365
399
|
assert_equal [], MarkdownTableFormatter.format_table(
|
366
400
|
lines: [],
|
367
|
-
column_count: 3
|
401
|
+
column_count: 3,
|
402
|
+
table: @table
|
368
403
|
)
|
369
404
|
end
|
370
405
|
|
@@ -382,7 +417,8 @@ class TestFormatTable < Minitest::Test
|
|
382
417
|
]
|
383
418
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
384
419
|
lines: lines,
|
385
|
-
column_count: column_count
|
420
|
+
column_count: column_count,
|
421
|
+
table: @table
|
386
422
|
)
|
387
423
|
end
|
388
424
|
|
@@ -398,12 +434,17 @@ class TestFormatTable < Minitest::Test
|
|
398
434
|
]
|
399
435
|
assert_equal expected, MarkdownTableFormatter.format_table(
|
400
436
|
lines: lines,
|
401
|
-
column_count: column_count
|
437
|
+
column_count: column_count,
|
438
|
+
table: @table
|
402
439
|
)
|
403
440
|
end
|
404
441
|
end
|
405
442
|
|
406
443
|
class TestFormatTable2 < Minitest::Test
|
444
|
+
def setup
|
445
|
+
@table = { delimiter: '|' }
|
446
|
+
end
|
447
|
+
|
407
448
|
def test_basic_formatting
|
408
449
|
lines = [
|
409
450
|
'| Name | Age | City |',
|
@@ -417,7 +458,8 @@ class TestFormatTable2 < Minitest::Test
|
|
417
458
|
]
|
418
459
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
419
460
|
lines: lines,
|
420
|
-
column_count: 3
|
461
|
+
column_count: 3,
|
462
|
+
table: @table
|
421
463
|
)
|
422
464
|
end
|
423
465
|
|
@@ -434,7 +476,8 @@ class TestFormatTable2 < Minitest::Test
|
|
434
476
|
]
|
435
477
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
436
478
|
lines: lines,
|
437
|
-
column_count: 3
|
479
|
+
column_count: 3,
|
480
|
+
table: @table
|
438
481
|
)
|
439
482
|
end
|
440
483
|
|
@@ -451,7 +494,8 @@ class TestFormatTable2 < Minitest::Test
|
|
451
494
|
]
|
452
495
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
453
496
|
lines: lines,
|
454
|
-
column_count: 4
|
497
|
+
column_count: 4,
|
498
|
+
table: @table
|
455
499
|
)
|
456
500
|
end
|
457
501
|
|
@@ -468,7 +512,8 @@ class TestFormatTable2 < Minitest::Test
|
|
468
512
|
]
|
469
513
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
470
514
|
lines: lines,
|
471
|
-
column_count: 3
|
515
|
+
column_count: 3,
|
516
|
+
table: @table
|
472
517
|
)
|
473
518
|
end
|
474
519
|
|
@@ -477,7 +522,8 @@ class TestFormatTable2 < Minitest::Test
|
|
477
522
|
expected_output = ['| Name | Age | City |']
|
478
523
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
479
524
|
lines: lines,
|
480
|
-
column_count: 3
|
525
|
+
column_count: 3,
|
526
|
+
table: @table
|
481
527
|
)
|
482
528
|
end
|
483
529
|
|
@@ -486,7 +532,8 @@ class TestFormatTable2 < Minitest::Test
|
|
486
532
|
expected_output = []
|
487
533
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
488
534
|
lines: lines,
|
489
|
-
column_count: 3
|
535
|
+
column_count: 3,
|
536
|
+
table: @table
|
490
537
|
)
|
491
538
|
end
|
492
539
|
|
@@ -501,7 +548,8 @@ class TestFormatTable2 < Minitest::Test
|
|
501
548
|
]
|
502
549
|
assert_equal expected_output, MarkdownTableFormatter.format_table(
|
503
550
|
lines: lines,
|
504
|
-
column_count: 3
|
551
|
+
column_count: 3,
|
552
|
+
table: @table
|
505
553
|
)
|
506
554
|
end
|
507
555
|
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
|