kramdown-ansi 0.4.1 → 0.5.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/.utilsrc +99 -0
- data/CHANGES.md +28 -0
- data/Rakefile +2 -1
- data/kramdown-ansi.gemspec +7 -6
- data/lib/kramdown/ansi/width.rb +53 -9
- data/lib/kramdown/ansi.rb +8 -8
- data/lib/kramdown/version.rb +1 -1
- data/spec/kramdown/ansi/pager_spec.rb +0 -2
- data/spec/kramdown/ansi/styles_spec.rb +0 -3
- data/spec/kramdown/ansi/width_spec.rb +0 -2
- data/spec/kramdown/ansi_spec.rb +3 -5
- data/spec/kramdown/ansi_table_spec.rb +51 -0
- data/spec/spec_helper.rb +63 -0
- metadata +21 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 737af675856867287e33a53bf18bbb08517b3743900132f826b77cdad9b47c01
|
|
4
|
+
data.tar.gz: f533ff7b8927579aead7c482039813091cf55796621febd5658a5c469d7e0957
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5578a1e962bf25fbc54f00be909cb53a647bc3e56f67934a984c37f8c4a156e1dd499e446aa549817c35fd83c26c31a0f975319b06dcc7e556e73ba39b5be9cf
|
|
7
|
+
data.tar.gz: b48b3cab8c7d2c05181efe12cd794be25a59d1319aaaa6ad26ae2a31b7a54311153f24076ae109a696c5cec791c958b6e6eba84bc2f3c9823c5feec9916ee825
|
data/.utilsrc
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# vim: set ft=ruby:
|
|
2
|
+
|
|
3
|
+
search do
|
|
4
|
+
prune_dirs /\A(\.svn|\.git|\.terraform|CVS|tmp|coverage|corpus|pkg|\.yardoc|doc)\z/
|
|
5
|
+
skip_files /(\A\.|\.sw[pon]\z|\.(log|fnm|jpg|jpeg|png|pdf|svg)\z|\A(tags|cscope\.out)\z|~\z)/i
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
discover do
|
|
9
|
+
prune_dirs /\A(\.svn|\.git|\.terraform|\.yardoc|CVS|tmp|coverage|corpus|pkg|\.yardoc|doc)\z/
|
|
10
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
|
11
|
+
index_expire_after 3_600
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
strip_spaces do
|
|
15
|
+
prune_dirs /\A(\..*|CVS|pkg|\.yardoc)\z/
|
|
16
|
+
skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
probe do
|
|
20
|
+
test_framework :rspec
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
ssh_tunnel do
|
|
24
|
+
terminal_multiplexer :tmux
|
|
25
|
+
login_session "/home/#{ENV['USER']}"
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
classify do
|
|
29
|
+
shift_path_by_default 1
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
code_indexer do
|
|
33
|
+
verbose false
|
|
34
|
+
|
|
35
|
+
gems = %w[
|
|
36
|
+
all_images
|
|
37
|
+
amatch
|
|
38
|
+
base64
|
|
39
|
+
bigdecimal
|
|
40
|
+
complex_config
|
|
41
|
+
date
|
|
42
|
+
debug
|
|
43
|
+
diff-lcs
|
|
44
|
+
docile
|
|
45
|
+
erb
|
|
46
|
+
excon
|
|
47
|
+
fileutils
|
|
48
|
+
gem_hadar
|
|
49
|
+
infobar
|
|
50
|
+
io-console
|
|
51
|
+
irb
|
|
52
|
+
json
|
|
53
|
+
kramdown
|
|
54
|
+
kramdown-ansi
|
|
55
|
+
kramdown-parser-gfm
|
|
56
|
+
logger
|
|
57
|
+
mize
|
|
58
|
+
more_math
|
|
59
|
+
net-http
|
|
60
|
+
nokogiri
|
|
61
|
+
ollama-ruby
|
|
62
|
+
openssl
|
|
63
|
+
ostruct
|
|
64
|
+
pp
|
|
65
|
+
prettyprint
|
|
66
|
+
prism
|
|
67
|
+
psych
|
|
68
|
+
racc
|
|
69
|
+
rake
|
|
70
|
+
rdoc
|
|
71
|
+
readline
|
|
72
|
+
reline
|
|
73
|
+
rexml
|
|
74
|
+
rspec
|
|
75
|
+
rspec-core
|
|
76
|
+
rspec-expectations
|
|
77
|
+
rspec-mocks
|
|
78
|
+
rspec-support
|
|
79
|
+
search_ui
|
|
80
|
+
shellwords
|
|
81
|
+
simplecov
|
|
82
|
+
simplecov-html
|
|
83
|
+
simplecov_json_formatter
|
|
84
|
+
stringio
|
|
85
|
+
sync
|
|
86
|
+
term-ansicolor
|
|
87
|
+
terminal-table
|
|
88
|
+
tins
|
|
89
|
+
tsort
|
|
90
|
+
unicode-display_width
|
|
91
|
+
uri
|
|
92
|
+
yaml
|
|
93
|
+
yard
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
paths {
|
|
97
|
+
%w[ lib ] + gems.map { `bundle show #{it}` }.map(&:chomp)
|
|
98
|
+
}
|
|
99
|
+
end
|
data/CHANGES.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changes
|
|
2
2
|
|
|
3
|
+
## 2026-03-21 v0.5.0
|
|
4
|
+
|
|
5
|
+
- Added `spec/kramdown/ansi_table_spec.rb` to the test suite and gemspec file
|
|
6
|
+
list.
|
|
7
|
+
- Updated `Kramdown::ANSI#convert_tr` to use column‑width ratios instead of a
|
|
8
|
+
fixed `full_width`.
|
|
9
|
+
- Refactored `Kramdown::ANSI::Width.wrap` to preserve ANSI escapes, clamp
|
|
10
|
+
lengths, and use a token‑based wrapping algorithm.
|
|
11
|
+
- Introduced `display_width` method in `Kramdown::ANSI::Width` to compute
|
|
12
|
+
visual width after stripping ANSI codes.
|
|
13
|
+
- Extracted ANSI escape removal logic into reusable
|
|
14
|
+
`Kramdown::ANSI::Width.remove_ansi_escapes`.
|
|
15
|
+
- Added lightweight `LoremIpsum` helper class in `spec/spec_helper.rb` for
|
|
16
|
+
deterministic dummy text.
|
|
17
|
+
- Updated `spec/kramdown/ansi_spec.rb` expectations to reflect new line‑break
|
|
18
|
+
behavior and added a direct `output.puts` call.
|
|
19
|
+
- Updated CI image configuration: install `build-base`, `yaml-dev`,
|
|
20
|
+
`openssl-dev`, `git`; removed `bundle update`; added before/after blocks;
|
|
21
|
+
removed `Gemfile.lock`.
|
|
22
|
+
- Added `.rspec` configuration with `--force-color` and exclusion of
|
|
23
|
+
`spec_helper`.
|
|
24
|
+
- Added `.utilsrc` configuration for util indexing, listing numerous gems and
|
|
25
|
+
test framework settings.
|
|
26
|
+
- Removed `require 'spec_helper'` from spec files, enabling colorized test
|
|
27
|
+
output.
|
|
28
|
+
- Added runtime dependency on `unicode-display_width` (~> **3.0**) for accurate
|
|
29
|
+
string width calculations.
|
|
30
|
+
|
|
3
31
|
## 2026-02-23 v0.4.1
|
|
4
32
|
|
|
5
33
|
- Updated the Ruby CI script to use `bundle exec` when running `rake spec`,
|
data/Rakefile
CHANGED
|
@@ -36,8 +36,9 @@ GemHadar do
|
|
|
36
36
|
|
|
37
37
|
dependency 'term-ansicolor', '~> 1.11'
|
|
38
38
|
dependency 'kramdown-parser-gfm', '~> 1.1'
|
|
39
|
-
dependency 'terminal-table', '~>
|
|
39
|
+
dependency 'terminal-table', '~> 4.0'
|
|
40
40
|
dependency 'json', '~> 2.0'
|
|
41
|
+
dependency 'unicode-display_width', '~> 3.0'
|
|
41
42
|
development_dependency 'all_images', '~> 0.4'
|
|
42
43
|
development_dependency 'rspec', '~> 3.2'
|
|
43
44
|
development_dependency 'debug'
|
data/kramdown-ansi.gemspec
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
|
-
# stub: kramdown-ansi 0.
|
|
2
|
+
# stub: kramdown-ansi 0.5.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.5.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]
|
|
@@ -13,14 +13,14 @@ Gem::Specification.new do |s|
|
|
|
13
13
|
s.email = "flori@ping.de".freeze
|
|
14
14
|
s.executables = ["md".freeze, "git-md".freeze]
|
|
15
15
|
s.extra_rdoc_files = ["README.md".freeze, "lib/kramdown/ansi.rb".freeze, "lib/kramdown/ansi/pager.rb".freeze, "lib/kramdown/ansi/styles.rb".freeze, "lib/kramdown/ansi/width.rb".freeze, "lib/kramdown/version.rb".freeze]
|
|
16
|
-
s.files = ["CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/git-md".freeze, "bin/md".freeze, "img/git-md.png".freeze, "img/md.png".freeze, "kramdown-ansi.gemspec".freeze, "lib/kramdown/ansi.rb".freeze, "lib/kramdown/ansi/pager.rb".freeze, "lib/kramdown/ansi/styles.rb".freeze, "lib/kramdown/ansi/width.rb".freeze, "lib/kramdown/version.rb".freeze, "spec/assets/README.ansi".freeze, "spec/assets/kitten.jpg".freeze, "spec/kramdown/ansi/pager_spec.rb".freeze, "spec/kramdown/ansi/styles_spec.rb".freeze, "spec/kramdown/ansi/width_spec.rb".freeze, "spec/kramdown/ansi_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
16
|
+
s.files = [".utilsrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/git-md".freeze, "bin/md".freeze, "img/git-md.png".freeze, "img/md.png".freeze, "kramdown-ansi.gemspec".freeze, "lib/kramdown/ansi.rb".freeze, "lib/kramdown/ansi/pager.rb".freeze, "lib/kramdown/ansi/styles.rb".freeze, "lib/kramdown/ansi/width.rb".freeze, "lib/kramdown/version.rb".freeze, "spec/assets/README.ansi".freeze, "spec/assets/kitten.jpg".freeze, "spec/kramdown/ansi/pager_spec.rb".freeze, "spec/kramdown/ansi/styles_spec.rb".freeze, "spec/kramdown/ansi/width_spec.rb".freeze, "spec/kramdown/ansi_spec.rb".freeze, "spec/kramdown/ansi_table_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
17
17
|
s.homepage = "https://github.com/flori/kramdown-ansi".freeze
|
|
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.8".freeze
|
|
22
22
|
s.summary = "Output markdown in the terminal with ANSI escape sequences".freeze
|
|
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_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
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_spec.rb".freeze, "spec/kramdown/ansi_table_spec.rb".freeze, "spec/spec_helper.rb".freeze]
|
|
24
24
|
|
|
25
25
|
s.specification_version = 4
|
|
26
26
|
|
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
|
31
31
|
s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
|
|
32
32
|
s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
|
|
33
33
|
s.add_runtime_dependency(%q<kramdown-parser-gfm>.freeze, ["~> 1.1".freeze])
|
|
34
|
-
s.add_runtime_dependency(%q<terminal-table>.freeze, ["~>
|
|
34
|
+
s.add_runtime_dependency(%q<terminal-table>.freeze, ["~> 4.0".freeze])
|
|
35
35
|
s.add_runtime_dependency(%q<json>.freeze, ["~> 2.0".freeze])
|
|
36
|
+
s.add_runtime_dependency(%q<unicode-display_width>.freeze, ["~> 3.0".freeze])
|
|
36
37
|
end
|
data/lib/kramdown/ansi/width.rb
CHANGED
|
@@ -27,24 +27,68 @@ module Kramdown::ANSI::Width
|
|
|
27
27
|
((Float(percentage) * Tins::Terminal.columns) / 100).floor
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
#
|
|
30
|
+
# Removes ANSI escape sequences from the given string.
|
|
31
|
+
#
|
|
32
|
+
# @param line [String] the string potentially containing ANSI escape codes.
|
|
33
|
+
# @return [String] the string with all ANSI escape sequences removed.
|
|
34
|
+
def remove_ansi_escapes(line)
|
|
35
|
+
line.to_s.gsub(/\e\[.*?m|\e\].*?(\e|\a)\\?/, '')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Calculates the display width of a string after removing ANSI escape
|
|
39
|
+
# sequences.
|
|
40
|
+
#
|
|
41
|
+
# @param line [String] the string to measure
|
|
42
|
+
# @return [Integer] the number of columns the string occupies in a terminal
|
|
43
|
+
def display_width(line)
|
|
44
|
+
Unicode::DisplayWidth.of(remove_ansi_escapes(line))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Wraps a string to a given width, either by percentage of terminal
|
|
48
|
+
# width or by an explicit character length.
|
|
31
49
|
#
|
|
32
50
|
# @param text [String] the text to wrap
|
|
33
|
-
# @option percentage [Numeric] the percentage
|
|
34
|
-
# @option length [Integer] the character
|
|
35
|
-
# @return [String] the wrapped
|
|
51
|
+
# @option percentage [Numeric] the percentage of terminal width to use
|
|
52
|
+
# @option length [Integer] the explicit character width to wrap to
|
|
53
|
+
# @return [String] the wrapped string, preserving ANSI escape sequences
|
|
36
54
|
# @raise [ArgumentError] if neither `percentage` nor `length` is provided
|
|
55
|
+
# @example
|
|
56
|
+
# Kramdown::ANSI::Width.wrap("Hello world!", percentage: 50)
|
|
57
|
+
# # => "Hello\nworld!"
|
|
37
58
|
def wrap(text, percentage: nil, length: nil)
|
|
38
59
|
percentage.nil? ^ length.nil? or
|
|
39
60
|
raise ArgumentError, "either pass percentage or length argument"
|
|
40
61
|
percentage and length ||= width(percentage:)
|
|
41
|
-
text
|
|
42
|
-
|
|
43
|
-
|
|
62
|
+
return text if length <= 0
|
|
63
|
+
begin
|
|
64
|
+
length = length.to_i
|
|
65
|
+
rescue FloatDomainError
|
|
66
|
+
return text
|
|
67
|
+
end
|
|
68
|
+
length = length.clamp(1..)
|
|
69
|
+
length_without_ansi = 0
|
|
70
|
+
result = ''
|
|
71
|
+
text.gsub(/(?<nws>\S+)|(?<ws>\s)/) do
|
|
72
|
+
token_value = $&
|
|
73
|
+
token_length = display_width(token_value)
|
|
74
|
+
if $~[:nws]
|
|
75
|
+
if length_without_ansi + token_length > length
|
|
76
|
+
length_without_ansi = token_length
|
|
77
|
+
if result[-1] == ' '
|
|
78
|
+
result[-1, 1] = "\n#{token_value}"
|
|
79
|
+
else
|
|
80
|
+
result << "\n#{token_value}"
|
|
81
|
+
end
|
|
82
|
+
else
|
|
83
|
+
length_without_ansi += token_length
|
|
84
|
+
result << token_value
|
|
85
|
+
end
|
|
44
86
|
else
|
|
45
|
-
|
|
87
|
+
length_without_ansi += token_length
|
|
88
|
+
result << token_value
|
|
46
89
|
end
|
|
47
|
-
end
|
|
90
|
+
end
|
|
91
|
+
result
|
|
48
92
|
end
|
|
49
93
|
|
|
50
94
|
# Truncates a given string to a specified length or percentage. If the text
|
data/lib/kramdown/ansi.rb
CHANGED
|
@@ -56,7 +56,7 @@ class Kramdown::ANSI < Kramdown::Converter::Base
|
|
|
56
56
|
# @return [String] a copy of the input string with all ANSI escape
|
|
57
57
|
# sequences removed
|
|
58
58
|
def self.ansi_escape(line)
|
|
59
|
-
|
|
59
|
+
Kramdown::ANSI::Width.remove_ansi_escapes(line)
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
62
|
|
|
@@ -457,14 +457,14 @@ class Kramdown::ANSI < Kramdown::Converter::Base
|
|
|
457
457
|
# addition of the row to the table instance
|
|
458
458
|
def convert_tr(el, opts)
|
|
459
459
|
return '' if el.children.empty?
|
|
460
|
-
full_width = width(percentage: 90)
|
|
461
460
|
cols = el.children.map { |c| convert(c, opts).strip }
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
}
|
|
461
|
+
return '' if cols.empty?
|
|
462
|
+
col_widths = cols.map { |c| display_width(c).size }
|
|
463
|
+
col_widths_sum = col_widths.sum
|
|
464
|
+
full_width = width(percentage: 90)
|
|
465
|
+
ratios = cols.each_with_index.map { |c, i| col_widths[i] / col_widths_sum.to_f }
|
|
466
|
+
wrapped_cols = cols.zip(ratios).map { |c, r| wrap(c, length: r * full_width) }
|
|
467
|
+
opts[:table] << wrapped_cols
|
|
468
468
|
''
|
|
469
469
|
end
|
|
470
470
|
|
data/lib/kramdown/version.rb
CHANGED
data/spec/kramdown/ansi_spec.rb
CHANGED
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
require 'pathname'
|
|
3
|
-
|
|
4
1
|
describe Kramdown::ANSI do
|
|
5
2
|
let :source do
|
|
6
3
|
File.read(Pathname.new(__dir__) + '..' + '..' + 'README.md')
|
|
@@ -11,7 +8,7 @@ describe Kramdown::ANSI do
|
|
|
11
8
|
ansi = described_class.parse(source)
|
|
12
9
|
expect(ansi).to include("\e[1m\e[4mDescription\e[0m\e[0m")
|
|
13
10
|
expect(ansi).to include("\e[1mKramdown::ANSI\e[0m")
|
|
14
|
-
expect(ansi).to include("\e[3min the
|
|
11
|
+
expect(ansi).to include("\e[3min the\nterminal\e[0m") # wrap adds linebreak
|
|
15
12
|
expect(ansi).to include("\e[34mgem install kramdown-ansi\n\e[0m")
|
|
16
13
|
expect(ansi).to include("\e[34mbundle install\e[0m")
|
|
17
14
|
expect(ansi).to include("This is the end.")
|
|
@@ -30,10 +27,11 @@ describe Kramdown::ANSI do
|
|
|
30
27
|
ansi = described_class.parse(source, ansi_styles:)
|
|
31
28
|
expect(ansi).to include("\e[31m\e[4mDescription\e[0m\e[0")
|
|
32
29
|
expect(ansi).to include("\e[32mKramdown::ANSI\e[0m")
|
|
33
|
-
expect(ansi).to include("\e[33min the
|
|
30
|
+
expect(ansi).to include("\e[33min the\nterminal\e[0m") # wrap adds linebreak
|
|
34
31
|
expect(ansi).to include("\e[1m\e[38;5;208mgem install kramdown-ansi\n\e[0m\e[0m")
|
|
35
32
|
expect(ansi).to include("\e[1m\e[38;5;208mbundle install\e[0m\e[0m")
|
|
36
33
|
expect(ansi).to include("This is the end.")
|
|
34
|
+
output.puts ansi
|
|
37
35
|
end
|
|
38
36
|
end
|
|
39
37
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
describe 'Kramdown::ANSI table' do
|
|
2
|
+
before do
|
|
3
|
+
allow(Tins::Terminal).to receive(:columns).and_return 80
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
lorem_cell = -> seed do
|
|
7
|
+
LoremIpsum.generate(paragraphs: 1, words_per_sentence: 5, seed:).strip
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
ansi_lorem_cell = -> seed do
|
|
11
|
+
lorem_cell.(seed).gsub(/\S+/) { |word|
|
|
12
|
+
Term::ANSIColor.send(%i[ bold italic color208 color248 ].sample) { word }
|
|
13
|
+
}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:no_ansi_markdown) do
|
|
17
|
+
<<~EOT
|
|
18
|
+
| Header 1 | Header 2 | Header 3 |
|
|
19
|
+
|----------|----------|----------|
|
|
20
|
+
| #{lorem_cell.(23)} | #{lorem_cell.(42)} | #{lorem_cell.(25)} |
|
|
21
|
+
EOT
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
let(:ansi_markdown) do
|
|
25
|
+
<<~EOT
|
|
26
|
+
| Header 1 | Header 2 | Header 3 |
|
|
27
|
+
|----------|----------|----------|
|
|
28
|
+
| #{ansi_lorem_cell.(23)} | #{ansi_lorem_cell.(42)} | #{ansi_lorem_cell.(25)} |
|
|
29
|
+
EOT
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'renders a table w/o ANSI styling and correct borders' do
|
|
33
|
+
no_ansi = Kramdown::ANSI.parse(no_ansi_markdown)
|
|
34
|
+
# The table should contain the table separator character
|
|
35
|
+
expect(no_ansi).to match(/─/)
|
|
36
|
+
# The generated LoremIpsum text should appear in the output
|
|
37
|
+
expect(no_ansi).to include(lorem_cell.(23)[0, 10])
|
|
38
|
+
# No raw markdown markers should remain
|
|
39
|
+
expect(no_ansi).not_to include('|')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it 'renders a table with ANSI styling and correct borders' do
|
|
43
|
+
ansi = Kramdown::ANSI.parse(ansi_markdown)
|
|
44
|
+
# The table should contain the table separator character
|
|
45
|
+
expect(ansi).to match(/─/)
|
|
46
|
+
# The generated LoremIpsum text should appear in the output
|
|
47
|
+
expect(ansi).to include(lorem_cell.(23)[0, 10])
|
|
48
|
+
# No raw markdown markers should remain
|
|
49
|
+
expect(ansi).not_to include('|')
|
|
50
|
+
end
|
|
51
|
+
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -7,6 +7,69 @@ rescue LoadError
|
|
|
7
7
|
end
|
|
8
8
|
require 'kramdown/ansi'
|
|
9
9
|
|
|
10
|
+
# A lightweight Lorem Ipsum generator.
|
|
11
|
+
#
|
|
12
|
+
# The generator uses a small pool of classic Latin words and
|
|
13
|
+
# randomly assembles them into sentences and paragraphs.
|
|
14
|
+
class LoremIpsum
|
|
15
|
+
# Generates Lorem Ipsum text with the specified number of paragraphs and
|
|
16
|
+
# average words per sentence.
|
|
17
|
+
#
|
|
18
|
+
# @param paragraphs [Integer] the number of paragraphs to generate (default: 3)
|
|
19
|
+
# @param words_per_sentence [Integer] the average number of words per
|
|
20
|
+
# sentence (default: 10)
|
|
21
|
+
# @return [String] the generated Lorem Ipsum text
|
|
22
|
+
def self.generate(paragraphs: 3, words_per_sentence: 10, seed: nil)
|
|
23
|
+
new.generate(paragraphs:, words_per_sentence:, seed:)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Default word pool (classic Lorem Ipsum source)
|
|
27
|
+
WORDS = %w[
|
|
28
|
+
lorem ipsum dolor sit amet consectetur adipiscing elit sed do
|
|
29
|
+
eiusmod tempor incididunt ut labore et dolore magna aliqua
|
|
30
|
+
enim ad minim veniam quis nostrud exercitation ullamco
|
|
31
|
+
laboris nisi ut aliquip ex ea commodo consequat duis aute
|
|
32
|
+
irure dolor in reprehenderit in voluptate velit esse
|
|
33
|
+
cillum dolore eu fugiat nulla pariatur
|
|
34
|
+
excepteur sint occaecat cupidatat non proident sunt
|
|
35
|
+
culpa qui officia deserunt mollit anim id est laborum
|
|
36
|
+
].freeze
|
|
37
|
+
|
|
38
|
+
# Generate a random word from the pool
|
|
39
|
+
def random_word
|
|
40
|
+
WORDS.sample random: @random
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Generate a sentence of a given length (in words)
|
|
44
|
+
# @param words [Integer] number of words in the sentence
|
|
45
|
+
# @return [String] a sentence ending with a period
|
|
46
|
+
def sentence(words: 8)
|
|
47
|
+
words.times.map { random_word }.join(' ').capitalize + '.'
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Generate a paragraph of a given number of sentences
|
|
51
|
+
# @param sentences [Integer] number of sentences in the paragraph
|
|
52
|
+
# @return [String] a paragraph ending with a newline
|
|
53
|
+
def paragraph(sentences: 4)
|
|
54
|
+
sentences.times.map { sentence }.join(' ') + "\n"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Generate a full Lorem Ipsum text
|
|
58
|
+
#
|
|
59
|
+
# @param paragraphs [Integer] number of paragraphs
|
|
60
|
+
# @param words_per_sentence [Integer] average words per sentence
|
|
61
|
+
# @return [String] the generated text
|
|
62
|
+
def generate(paragraphs: 3, words_per_sentence: 10, seed: nil)
|
|
63
|
+
@random = seed ? Random.new(seed) : Random.new
|
|
64
|
+
paragraphs.times.map do
|
|
65
|
+
# For a bit of natural variation, pick a random number
|
|
66
|
+
# of sentences around the requested average.
|
|
67
|
+
sentences = @random.rand(words_per_sentence / 2..words_per_sentence * 2)
|
|
68
|
+
paragraph(sentences: sentences)
|
|
69
|
+
end.join("\n")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
10
73
|
def asset(name)
|
|
11
74
|
File.join(__dir__, 'assets', name)
|
|
12
75
|
end
|
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.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Frank
|
|
@@ -113,14 +113,14 @@ dependencies:
|
|
|
113
113
|
requirements:
|
|
114
114
|
- - "~>"
|
|
115
115
|
- !ruby/object:Gem::Version
|
|
116
|
-
version: '
|
|
116
|
+
version: '4.0'
|
|
117
117
|
type: :runtime
|
|
118
118
|
prerelease: false
|
|
119
119
|
version_requirements: !ruby/object:Gem::Requirement
|
|
120
120
|
requirements:
|
|
121
121
|
- - "~>"
|
|
122
122
|
- !ruby/object:Gem::Version
|
|
123
|
-
version: '
|
|
123
|
+
version: '4.0'
|
|
124
124
|
- !ruby/object:Gem::Dependency
|
|
125
125
|
name: json
|
|
126
126
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -135,6 +135,20 @@ dependencies:
|
|
|
135
135
|
- - "~>"
|
|
136
136
|
- !ruby/object:Gem::Version
|
|
137
137
|
version: '2.0'
|
|
138
|
+
- !ruby/object:Gem::Dependency
|
|
139
|
+
name: unicode-display_width
|
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
|
141
|
+
requirements:
|
|
142
|
+
- - "~>"
|
|
143
|
+
- !ruby/object:Gem::Version
|
|
144
|
+
version: '3.0'
|
|
145
|
+
type: :runtime
|
|
146
|
+
prerelease: false
|
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
148
|
+
requirements:
|
|
149
|
+
- - "~>"
|
|
150
|
+
- !ruby/object:Gem::Version
|
|
151
|
+
version: '3.0'
|
|
138
152
|
description: |
|
|
139
153
|
Kramdown::ANSI: A library for rendering Markdown(ish) documents with
|
|
140
154
|
beautiful ANSI escape sequences in the terminal.
|
|
@@ -151,6 +165,7 @@ extra_rdoc_files:
|
|
|
151
165
|
- lib/kramdown/ansi/width.rb
|
|
152
166
|
- lib/kramdown/version.rb
|
|
153
167
|
files:
|
|
168
|
+
- ".utilsrc"
|
|
154
169
|
- CHANGES.md
|
|
155
170
|
- Gemfile
|
|
156
171
|
- LICENSE
|
|
@@ -172,6 +187,7 @@ files:
|
|
|
172
187
|
- spec/kramdown/ansi/styles_spec.rb
|
|
173
188
|
- spec/kramdown/ansi/width_spec.rb
|
|
174
189
|
- spec/kramdown/ansi_spec.rb
|
|
190
|
+
- spec/kramdown/ansi_table_spec.rb
|
|
175
191
|
- spec/spec_helper.rb
|
|
176
192
|
homepage: https://github.com/flori/kramdown-ansi
|
|
177
193
|
licenses:
|
|
@@ -195,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
195
211
|
- !ruby/object:Gem::Version
|
|
196
212
|
version: '0'
|
|
197
213
|
requirements: []
|
|
198
|
-
rubygems_version: 4.0.
|
|
214
|
+
rubygems_version: 4.0.8
|
|
199
215
|
specification_version: 4
|
|
200
216
|
summary: Output markdown in the terminal with ANSI escape sequences
|
|
201
217
|
test_files:
|
|
@@ -203,4 +219,5 @@ test_files:
|
|
|
203
219
|
- spec/kramdown/ansi/styles_spec.rb
|
|
204
220
|
- spec/kramdown/ansi/width_spec.rb
|
|
205
221
|
- spec/kramdown/ansi_spec.rb
|
|
222
|
+
- spec/kramdown/ansi_table_spec.rb
|
|
206
223
|
- spec/spec_helper.rb
|