kramdown-ansi 0.7.0 → 0.8.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/CHANGES.md +29 -0
- data/kramdown-ansi.gemspec +4 -4
- data/lib/kramdown/ansi/width.rb +3 -1
- data/lib/kramdown/ansi.rb +31 -19
- data/lib/kramdown/version.rb +1 -1
- data/spec/assets/tables.ansi +58 -57
- metadata +4 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bfce0110800a14de98f3322fa646e4432af3a51fcda9c278d5c631d322c2384d
|
|
4
|
+
data.tar.gz: fdad876925cd1ecab465d491b8cca2024dbc40b2e8d103794303b83e316aff3f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 624287e2ab60beda1ce2ad7ce0ae3e68feeb8ad430b46828c7af3ee4833dd7d92c8a726919c4ebf6289a35fe79600d9756983e735403ef2269fa1ed3fd00a4a2
|
|
7
|
+
data.tar.gz: 795ffcabcd29c3910d1da3fca407ab2c09d85a416f25b0122353f0176ab59dcb424e869d9b4fac149cde62a03c1792f3b3134d24fe85b0b2c507112e8a181d41
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,34 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-10-29 v0.8.0
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- Fixed table width overflow by restructuring column width calculation from
|
|
8
|
+
per-row to per-table in `convert_table`, ensuring `Terminal::Table` is not
|
|
9
|
+
forced wider than the terminal by a single row's content distribution.
|
|
10
|
+
- Fixed a bug in `Kramdown::ANSI::Width.wrap` where a newline was incorrectly
|
|
11
|
+
prepended to the first token when it exceeded the target length, eliminating
|
|
12
|
+
phantom blank lines in narrow table cells.
|
|
13
|
+
- Subtracted table chrome (border, padding, and separator overhead) from the
|
|
14
|
+
column width budget in `convert_table` to prevent tables from exceeding
|
|
15
|
+
width.
|
|
16
|
+
|
|
17
|
+
### Improvements
|
|
18
|
+
|
|
19
|
+
- Simplified `convert_tr` to read pre-computed column widths and wrap each cell
|
|
20
|
+
to its fixed budget.
|
|
21
|
+
|
|
22
|
+
### Build & CI
|
|
23
|
+
|
|
24
|
+
- Updated the minimum version of the `gem_hadar` development dependency to
|
|
25
|
+
**2.21.0**.
|
|
26
|
+
- Bumped `rubygems_version` to **4.0.23**.
|
|
27
|
+
|
|
28
|
+
### Testing
|
|
29
|
+
|
|
30
|
+
- Regenerated `spec/assets/tables.ansi` golden file.
|
|
31
|
+
|
|
3
32
|
## 2026-10-22 v0.7.0
|
|
4
33
|
|
|
5
34
|
### Fixes
|
data/kramdown-ansi.gemspec
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: kramdown-ansi 0.
|
|
2
|
+
# stub: kramdown-ansi 0.8.0 ruby lib
|
|
3
3
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "kramdown-ansi".freeze
|
|
6
|
-
s.version = "0.
|
|
6
|
+
s.version = "0.8.0".freeze
|
|
7
7
|
|
|
8
8
|
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
|
|
9
9
|
s.require_paths = ["lib".freeze]
|
|
@@ -18,13 +18,13 @@ Gem::Specification.new do |s|
|
|
|
18
18
|
s.licenses = ["MIT".freeze]
|
|
19
19
|
s.rdoc_options = ["--title".freeze, "Kramdown-ansi - Output markdown in the terminal with ANSI escape sequences".freeze, "--main".freeze, "README.md".freeze]
|
|
20
20
|
s.required_ruby_version = Gem::Requirement.new(">= 3.1".freeze)
|
|
21
|
-
s.rubygems_version = "4.0.
|
|
21
|
+
s.rubygems_version = "4.0.23".freeze
|
|
22
22
|
s.summary = "Output markdown in the terminal with ANSI escape sequences".freeze
|
|
23
23
|
s.test_files = ["spec/kramdown/ansi/pager_spec.rb".freeze, "spec/kramdown/ansi/styles_spec.rb".freeze, "spec/kramdown/ansi/width_spec.rb".freeze, "spec/kramdown/ansi_golden_spec.rb".freeze, "spec/kramdown/ansi_spec.rb".freeze, "spec/kramdown/ansi_table_spec.rb".freeze, "spec/kramdown/render_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
24
24
|
|
|
25
25
|
s.specification_version = 4
|
|
26
26
|
|
|
27
|
-
s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.
|
|
27
|
+
s.add_development_dependency(%q<gem_hadar>.freeze, [">= 2.21.0".freeze])
|
|
28
28
|
s.add_development_dependency(%q<all_images>.freeze, ["~> 0.4".freeze])
|
|
29
29
|
s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2".freeze])
|
|
30
30
|
s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
|
data/lib/kramdown/ansi/width.rb
CHANGED
|
@@ -78,7 +78,9 @@ module Kramdown::ANSI::Width
|
|
|
78
78
|
if $~[:nws]
|
|
79
79
|
if length_without_ansi + token_length > length
|
|
80
80
|
length_without_ansi = token_length
|
|
81
|
-
if result
|
|
81
|
+
if result.empty?
|
|
82
|
+
result = token_value
|
|
83
|
+
elsif result[-1] == ' '
|
|
82
84
|
result[-1, 1] = "\n#{token_value}"
|
|
83
85
|
else
|
|
84
86
|
result << "\n#{token_value}"
|
data/lib/kramdown/ansi.rb
CHANGED
|
@@ -472,6 +472,29 @@ class Kramdown::ANSI < Kramdown::Converter::Base
|
|
|
472
472
|
end
|
|
473
473
|
return newline rows.join("\n")
|
|
474
474
|
end
|
|
475
|
+
# Compute per-column budgets from the widest cell in each column
|
|
476
|
+
# across all rows. Terminal::Table sizes each column to its widest
|
|
477
|
+
# cell, so per-row ratios would produce columns wider than the
|
|
478
|
+
# terminal budget.
|
|
479
|
+
max_w = Hash.new(0)
|
|
480
|
+
el.children.each do |section|
|
|
481
|
+
next unless %i[thead tbody tfoot].include?(section.type)
|
|
482
|
+
section.children.each do |row|
|
|
483
|
+
row.children.each_with_index do |cell, i|
|
|
484
|
+
max_w[i] = [max_w[i], display_width(convert(cell, opts).strip)].max
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
n = max_w.keys.map(&:to_i).max.to_i + 1
|
|
489
|
+
total = max_w.values.sum
|
|
490
|
+
budget = width(percentage: 90) - (3 * n + 1)
|
|
491
|
+
col_w = if total.zero?
|
|
492
|
+
same = (budget.to_f / n).to_i
|
|
493
|
+
Array.new(n, same)
|
|
494
|
+
else
|
|
495
|
+
(0...n).map { |i| ((max_w[i].to_f / total) * budget).to_i }
|
|
496
|
+
end
|
|
497
|
+
opts[:table_col_widths] = col_w
|
|
475
498
|
table = Terminal::Table.new
|
|
476
499
|
table.style = {
|
|
477
500
|
all_separators: true,
|
|
@@ -533,33 +556,23 @@ class Kramdown::ANSI < Kramdown::Converter::Base
|
|
|
533
556
|
''
|
|
534
557
|
end
|
|
535
558
|
|
|
536
|
-
# The convert_tr method processes a table row element by
|
|
537
|
-
#
|
|
538
|
-
#
|
|
559
|
+
# The convert_tr method processes a table row element by wrapping each cell
|
|
560
|
+
# to the pre-computed column width and adding the formatted row to the
|
|
561
|
+
# terminal table instance.
|
|
539
562
|
#
|
|
540
563
|
# @param el [Kramdown::Element] the table row element to convert
|
|
541
564
|
# @param opts [Hash] conversion options containing context for processing
|
|
565
|
+
# (must include :table and :table_col_widths)
|
|
542
566
|
# @return [String] an empty string to indicate successful processing and
|
|
543
567
|
# addition of the row to the table instance
|
|
544
568
|
def convert_tr(el, opts)
|
|
545
569
|
return '' if el.children.empty?
|
|
546
|
-
|
|
570
|
+
col_w = opts[:table_col_widths]
|
|
571
|
+
cols = el.children.each_with_index.map do |c, i|
|
|
547
572
|
stripped = convert(c, opts).strip
|
|
548
|
-
stripped.empty? ? ' ' : stripped
|
|
573
|
+
stripped.empty? ? ' ' : wrap(stripped, length: col_w[i])
|
|
549
574
|
end
|
|
550
|
-
|
|
551
|
-
col_widths = cols.map { |c| display_width(c) }
|
|
552
|
-
col_widths_sum = col_widths.sum
|
|
553
|
-
full_width = width(percentage: 90)
|
|
554
|
-
ratios = cols.each_with_index.map do |c, i|
|
|
555
|
-
if col_widths_sum.zero?
|
|
556
|
-
1.0 / cols.size
|
|
557
|
-
else
|
|
558
|
-
col_widths[i] / col_widths_sum.to_f
|
|
559
|
-
end
|
|
560
|
-
end
|
|
561
|
-
wrapped_cols = cols.zip(ratios).map { |c, r| wrap(c, length: r * full_width) }
|
|
562
|
-
opts[:table] << wrapped_cols
|
|
575
|
+
opts[:table] << cols
|
|
563
576
|
''
|
|
564
577
|
end
|
|
565
578
|
|
|
@@ -662,5 +675,4 @@ class Kramdown::ANSI < Kramdown::Converter::Base
|
|
|
662
675
|
@ansi_styles.apply(name, &block)
|
|
663
676
|
end
|
|
664
677
|
end
|
|
665
|
-
|
|
666
678
|
Kramdown::Converter.const_set(:Ansi, Kramdown::ANSI)
|
data/lib/kramdown/version.rb
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
# by hand; it is rewritten on every `rake version` invocation.
|
|
6
6
|
module Kramdown
|
|
7
7
|
# The current version of the Kramdown gem as a String.
|
|
8
|
-
VERSION = '0.
|
|
8
|
+
VERSION = '0.8.0'
|
|
9
9
|
VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
|
|
10
10
|
VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
|
|
11
11
|
VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
|
data/spec/assets/tables.ansi
CHANGED
|
@@ -286,60 +286,61 @@ a | b
|
|
|
286
286
|
|
|
287
287
|
────────────────────────────────────────────────────────────────────────────────
|
|
288
288
|
|
|
289
|
-
|
|
290
|
-
│ Case │ What It Stresses
|
|
291
|
-
|
|
292
|
-
│ 01 │ Column count validation / overflow / underflow
|
|
293
|
-
|
|
294
|
-
│ 02 │ Pipe-stripping logic (leading/trailing optional)
|
|
295
|
-
|
|
296
|
-
│ 03 │ Escape sequence handling ([34m\|[0m)
|
|
297
|
-
|
|
298
|
-
│ 04 │ Empty-string cell rendering, border alignment
|
|
299
|
-
|
|
300
|
-
│ 05 │ Single-column edge (degenerate table)
|
|
301
|
-
|
|
302
|
-
│ 06 │ Zero data rows — does it draw a header-only box?
|
|
303
|
-
|
|
304
|
-
│ 07 │ Consecutive tables — does the second become data of the
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
289
|
+
╭──────┬─────────────────────────────────────────────────────────╮
|
|
290
|
+
│ Case │ What It Stresses │
|
|
291
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
292
|
+
│ 01 │ Column count validation / overflow / underflow │
|
|
293
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
294
|
+
│ 02 │ Pipe-stripping logic (leading/trailing optional) │
|
|
295
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
296
|
+
│ 03 │ Escape sequence handling ([34m\|[0m) │
|
|
297
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
298
|
+
│ 04 │ Empty-string cell rendering, border alignment │
|
|
299
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
300
|
+
│ 05 │ Single-column edge (degenerate table) │
|
|
301
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
302
|
+
│ 06 │ Zero data rows — does it draw a header-only box? │
|
|
303
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
304
|
+
│ 07 │ Consecutive tables — does the second become data of the │
|
|
305
|
+
│ │ first? │
|
|
306
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
307
|
+
│ 08 │ Unicode width calculation for column sizing │
|
|
308
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
309
|
+
│ 09 │ Inline markdown rendering [3minside[0m a table cell │
|
|
310
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
311
|
+
│ 10 │ Alignment row with fewer columns than header │
|
|
312
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
313
|
+
│ 11 │ Blank line splitting one table into two │
|
|
314
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
315
|
+
│ 12 │ Whitespace normalization / trimming │
|
|
316
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
317
|
+
│ 13 │ Raw HTML + [34m<br>[0m in cell context │
|
|
318
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
319
|
+
│ 14 │ Cell with only whitespace — empty or not? │
|
|
320
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
321
|
+
│ 15 │ Very wide table — does it wrap or overflow? │
|
|
322
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
323
|
+
│ 16 │ Non-standard alignment markers │
|
|
324
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
325
|
+
│ 17 │ Table at doc start, glued to following header │
|
|
326
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
327
|
+
│ 18 │ Table glued to preceding header (no blank before) │
|
|
328
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
329
|
+
│ 19 │ Single col, missing closing pipe on header │
|
|
330
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
331
|
+
│ 20 │ Not a table: single pipe line │
|
|
332
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
333
|
+
│ 21 │ Not a table: header + sep, no body, missing pipe │
|
|
334
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
335
|
+
│ 22 │ Table after code block, no blank between │
|
|
336
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
337
|
+
│ 23 │ Table after list item, no blank between │
|
|
338
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
339
|
+
│ 24 │ No leading pipe on separator row │
|
|
340
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
341
|
+
│ 25 │ No leading pipe on body row │
|
|
342
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
343
|
+
│ 26 │ Indented table inside ordered list item │
|
|
344
|
+
├──────┼─────────────────────────────────────────────────────────┤
|
|
345
|
+
│ 27 │ Not a table just a pipe in a sentence │
|
|
346
|
+
╰──────┴─────────────────────────────────────────────────────────╯
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kramdown-ansi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.8.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -15,14 +15,14 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 2.
|
|
18
|
+
version: 2.21.0
|
|
19
19
|
type: :development
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - ">="
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 2.
|
|
25
|
+
version: 2.21.0
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: all_images
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -233,7 +233,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
233
233
|
- !ruby/object:Gem::Version
|
|
234
234
|
version: '0'
|
|
235
235
|
requirements: []
|
|
236
|
-
rubygems_version: 4.0.
|
|
236
|
+
rubygems_version: 4.0.23
|
|
237
237
|
specification_version: 4
|
|
238
238
|
summary: Output markdown in the terminal with ANSI escape sequences
|
|
239
239
|
test_files:
|