kramdown-ansi 0.4.1 β†’ 0.6.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.
@@ -1,6 +1,8 @@
1
- require 'spec_helper'
2
-
3
1
  describe Kramdown::ANSI::Width do
2
+ let :ansi do
3
+ Term::ANSIColor
4
+ end
5
+
4
6
  before do
5
7
  allow(Tins::Terminal).to receive(:columns).and_return 80
6
8
  end
@@ -60,12 +62,52 @@ describe Kramdown::ANSI::Width do
60
62
  expect(truncated.size).to eq 64
61
63
  end
62
64
 
65
+ it 'can truncate ansi escape sequences with length' do
66
+ truncated = described_class.truncate([ ansi.red { ?A * 10 }, ansi.green { ?A * 10 } ] * 5 * ' ', length: 64)
67
+ expect(truncated).to eq(
68
+ "\e[31mAAAAAAAAAA\e[0m \e[32mAAAAAAAAAA\e[0m \e[31mAAAAAAAAAA\e[0m \e[32mAAAAAAAAAA\e[0m \e[31mAAAAAAAAAA\e[0m \e[32mAAAAAAAA…\e[0m"
69
+ )
70
+ expect(Term::ANSIColor.uncolor {truncated }.size).to eq 64
71
+ end
72
+
73
+ it 'can truncate wide emojis with length' do
74
+ truncated = described_class.truncate('ABC' + ?😍 * 10 + 'DEF', length: 10)
75
+ expect(truncated).to eq("ABCπŸ˜πŸ˜πŸ˜β€¦")
76
+ expect(truncated.size).to eq 7
77
+ expect(described_class.display_width(truncated)).to eq 10
78
+ truncated = described_class.truncate('AB' + ?😍 * 10 + 'DEF', length: 10)
79
+ expect(truncated).to eq("ABπŸ˜πŸ˜πŸ˜β€¦")
80
+ expect(truncated.size).to eq 6
81
+ expect(described_class.display_width(truncated)).to eq 9
82
+ truncated = described_class.truncate('A' + ?😍 * 10 + 'DEF', length: 10)
83
+ expect(truncated).to eq("AπŸ˜πŸ˜πŸ˜πŸ˜β€¦")
84
+ expect(truncated.size).to eq 6
85
+ expect(described_class.display_width(truncated)).to eq 10
86
+ truncated = described_class.truncate('A' * 5 + ?😍 + 'B' * 5, length: 10)
87
+ expect(truncated).to eq("AAAAA😍BB…")
88
+ expect(truncated.size).to eq 9
89
+ expect(described_class.display_width(truncated)).to eq 10
90
+ truncated = described_class.truncate('A' * 3 + ?😍 + 'B' + ?😁 + 'C' * 5, length: 10)
91
+ expect(truncated).to eq("AAA😍B😁C…")
92
+ expect(truncated.size).to eq 8
93
+ expect(described_class.display_width(truncated)).to eq 10
94
+ truncated = described_class.truncate('A' * 3 + ?😍 + ansi.red { 'B' } + ?😁 + 'C' * 5, length: 10)
95
+ expect(truncated).to eq("AAA😍\e[31mB\e[0m😁C…\e[0m")
96
+ expect(truncated.size).to eq 21
97
+ expect(described_class.display_width(truncated)).to eq 10
98
+ end
99
+
63
100
  it 'cannot truncate if not necessary' do
64
101
  text = [ ?A * 10 ] * 5 * ' '
65
102
  truncated = described_class.truncate(text, length: 54)
66
103
  expect(truncated).to eq text
67
104
  end
68
105
 
106
+ it 'can truncate empty strings' do
107
+ truncated = described_class.truncate('', length: 23)
108
+ expect(truncated).to be_empty
109
+ end
110
+
69
111
  it 'can truncate with length 0' do
70
112
  truncated = described_class.truncate([ ?A * 10 ] * 10 * ' ', length: 0)
71
113
  expect(truncated).to be_empty
@@ -78,5 +120,51 @@ describe Kramdown::ANSI::Width do
78
120
  )
79
121
  expect(truncated.size).to eq 64
80
122
  end
123
+
124
+ it 'keeps pure ANSI strings (no chars)' do
125
+ truncated = described_class.truncate(ansi.red { '' }, length: 10)
126
+ expect(truncated).to eq "\e[31m\e[0m"
127
+ expect(truncated.size).to eq 9
128
+ end
129
+
130
+ it 'handles zero-width characters correctly' do
131
+ src = "A#{("\u200d"*10)}B"
132
+ truncated = described_class.truncate(src, length: 3)
133
+ expect(described_class.display_width(truncated)).to eq(2)
134
+ expect(truncated).to match "A.*B"
135
+ end
136
+
137
+ it 'preserves newlines in multi-line text' do
138
+ truncated = described_class.truncate("hello\nworld", length: 8)
139
+ expect(truncated).to include("\n")
140
+ expect(described_class.display_width(truncated)).to eq 8
141
+ end
142
+
143
+ it 'supports multi‑cell ellipsis' do
144
+ truncated = described_class.truncate('ABC' + ?πŸ˜‡ * 10, length: 8, ellipsis: '… (more)')
145
+ expect(truncated).to eq "… (more)"
146
+ expect(described_class.display_width(truncated)).to eq 8
147
+ expect(truncated.length).to eq 8
148
+ end
149
+
150
+ it 'appends reset if truncated after an escape that lacks reset' do
151
+ truncated = described_class.truncate(ansi.red { 'Hello' }, length: 4)
152
+ expect(truncated).to eq "\e[31mHel…\e[0m"
153
+ expect(described_class.remove_ansi_escapes(truncated).size).to eq 4
154
+ end
155
+
156
+ it 'appends single reset for nested styles when truncated' do
157
+ truncated = described_class.truncate(ansi.red { ansi.bold { 'Hi' } }, length: 2)
158
+ expect(truncated).to eq "\e[31m\e[1mH…\e[0m"
159
+ expect(described_class.display_width(truncated)).to eq 2
160
+ end
161
+
162
+ it 'omits escapes that fall after the truncation point' do
163
+ src = "#{ansi.red { 'A' }}B#{ansi.green { 'C' }}D"
164
+ truncated = described_class.truncate(src, length: 2)
165
+ expect(truncated).not_to include "\e[32m"
166
+ expect(truncated).to eq "\e[31mA…\e[0m"
167
+ expect(described_class.display_width(truncated)).to eq 2
168
+ end
81
169
  end
82
170
  end
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Kramdown::ANSI golden files' do
4
+ before do
5
+ allow(Tins::Terminal).to receive(:columns).and_return 80
6
+ end
7
+
8
+ Dir[File.join(__dir__, '../assets/*.md')].each do |md|
9
+ name = File.basename(md, '.md')
10
+ expected_path = md.sub('.md', '.ansi')
11
+
12
+ it "renders #{name} matching golden file" do
13
+ skip "no golden file at #{expected_path}" unless File.exist?(expected_path)
14
+ expected = File.read(expected_path)
15
+ actual = Kramdown::ANSI.parse(File.read(md))
16
+ expect(actual).to eq(expected)
17
+ end
18
+ end
19
+ end
@@ -1,7 +1,8 @@
1
- require 'spec_helper'
2
- require 'pathname'
3
-
4
1
  describe Kramdown::ANSI do
2
+ before do
3
+ allow(Tins::Terminal).to receive(:columns).and_return 80
4
+ end
5
+
5
6
  let :source do
6
7
  File.read(Pathname.new(__dir__) + '..' + '..' + 'README.md')
7
8
  end
@@ -11,9 +12,9 @@ describe Kramdown::ANSI do
11
12
  ansi = described_class.parse(source)
12
13
  expect(ansi).to include("\e[1m\e[4mDescription\e[0m\e[0m")
13
14
  expect(ansi).to include("\e[1mKramdown::ANSI\e[0m")
14
- expect(ansi).to include("\e[3min the terminal\e[0m")
15
15
  expect(ansi).to include("\e[34mgem install kramdown-ansi\n\e[0m")
16
16
  expect(ansi).to include("\e[34mbundle install\e[0m")
17
+ expect(ansi).to include("Dialog:\n β€œ\e[2mWhat's that, Fluffy?\n β€˜That's my new friend.’\e[0m”")
17
18
  expect(ansi).to include("This is the end.")
18
19
  output.puts ansi
19
20
  end
@@ -26,14 +27,15 @@ describe Kramdown::ANSI do
26
27
  strong: %i[ green ],
27
28
  em: %i[ yellow ],
28
29
  code: %i[ bold color208 ],
30
+ blockquote: %i[ magenta ],
29
31
  )
30
32
  ansi = described_class.parse(source, ansi_styles:)
31
33
  expect(ansi).to include("\e[31m\e[4mDescription\e[0m\e[0")
32
34
  expect(ansi).to include("\e[32mKramdown::ANSI\e[0m")
33
- expect(ansi).to include("\e[33min the terminal\e[0m")
34
35
  expect(ansi).to include("\e[1m\e[38;5;208mgem install kramdown-ansi\n\e[0m\e[0m")
35
- expect(ansi).to include("\e[1m\e[38;5;208mbundle install\e[0m\e[0m")
36
+ expect(ansi).to include("Dialog:\n β€œ\e[35mWhat's that, Fluffy?\n β€˜That's my new friend.’\e[0m”")
36
37
  expect(ansi).to include("This is the end.")
38
+ output.puts ansi
37
39
  end
38
40
  end
39
41
  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
@@ -0,0 +1,156 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Kramdown::ANSI rendering' do
4
+ before do
5
+ allow(Tins::Terminal).to receive(:columns).and_return 80
6
+ end
7
+
8
+ subject(:render) { Kramdown::ANSI.parse(md) }
9
+
10
+ describe 'headers' do
11
+ context 'level 1' do
12
+ let(:md) { "# Hello\n" }
13
+ it 'applies bold+underline' do
14
+ expect(render).to eq "\e[1m\e[4mHello\e[0m\e[0m\n"
15
+ end
16
+ end
17
+
18
+ context 'level 2' do
19
+ let(:md) { "## World\n" }
20
+ it 'applies bold+underline' do
21
+ expect(render).to eq "\e[1m\e[4mWorld\e[0m\e[0m\n"
22
+ end
23
+ end
24
+
25
+ context 'level 3' do
26
+ let(:md) { "### Deep\n" }
27
+ it 'applies bold+underline' do
28
+ expect(render).to eq "\e[1m\e[4mDeep\e[0m\e[0m\n"
29
+ end
30
+ end
31
+ end
32
+
33
+ describe 'inline emphasis' do
34
+ context 'strong' do
35
+ let(:md) { "This is **bold** text.\n" }
36
+ it 'wraps in bold' do
37
+ expect(render).to eq "This is \e[1mbold\e[0m text.\n"
38
+ end
39
+ end
40
+
41
+ context 'emphasis' do
42
+ let(:md) { "This is *italic* text.\n" }
43
+ it 'wraps in italic' do
44
+ expect(render).to eq "This is \e[3mitalic\e[0m text.\n"
45
+ end
46
+ end
47
+
48
+ context 'strikethrough' do
49
+ let(:md) { "This is ~~gone~~ text.\n" }
50
+ it 'wraps in strikethrough' do
51
+ expect(render).to eq "This is \e[9mgone\e[0m text.\n"
52
+ end
53
+ end
54
+
55
+ context 'code span' do
56
+ let(:md) { "Use `puts` here.\n" }
57
+ it 'wraps in blue' do
58
+ expect(render).to eq "Use \e[34mputs\e[0m here.\n"
59
+ end
60
+ end
61
+
62
+ context 'mixed inline' do
63
+ let(:md) { "A **bold** and *em* and `code` word.\n" }
64
+ it 'applies each style independently' do
65
+ expect(render).to eq(
66
+ "A \e[1mbold\e[0m and \e[3mem\e[0m and \e[34mcode\e[0m word.\n"
67
+ )
68
+ end
69
+ end
70
+ end
71
+
72
+ describe 'code blocks' do
73
+ context 'fenced with language' do
74
+ let(:md) { "```ruby\nputs \"hi\"\n```\n" }
75
+ it 'applies code style to content' do
76
+ expect(render).to eq "\e[34mputs \"hi\"\n\e[0m"
77
+ end
78
+ end
79
+
80
+ context 'fenced without language' do
81
+ let(:md) { "```\nplain code\n```\n" }
82
+ it 'applies code style to content' do
83
+ expect(render).to eq "\e[34mplain code\n\e[0m"
84
+ end
85
+ end
86
+ end
87
+
88
+ describe 'blockquotes' do
89
+ context 'single level' do
90
+ let(:md) { "> quoted line\n" }
91
+ it 'wraps in faint + double quotes' do
92
+ expect(render).to eq " β€œ\e[2mquoted line\e[0m”\n"
93
+ end
94
+ end
95
+
96
+ context 'nested' do
97
+ let(:md) { "> > nested\n" }
98
+ it 'cycles to single quotes for inner level' do
99
+ expect(render).to eq " β€œ\e[2mβ€˜nested’\e[0m”\n"
100
+ end
101
+ end
102
+ end
103
+
104
+ describe 'horizontal rule' do
105
+ let(:md) { "---\n" }
106
+ it 'renders full-width unicode line' do
107
+ expect(render).to eq((?─ * 80) + "\n")
108
+ end
109
+ end
110
+
111
+ describe 'lists' do
112
+ context 'unordered' do
113
+ let(:md) { "- one\n- two\n" }
114
+ it 'prefixes with bullet' do
115
+ expect(render).to eq "Β· one\n\nΒ· two\n\n"
116
+ end
117
+ end
118
+
119
+ context 'ordered' do
120
+ let(:md) { "1. first\n2. second\n" }
121
+ it 'prefixes with sequential numbers' do
122
+ expect(render).to eq "1. first\n\n2. second\n\n"
123
+ end
124
+ end
125
+
126
+ context 'nested unordered' do
127
+ let(:md) { "- one\n - sub\n- two\n" }
128
+ it 'indents nested items by 2 spaces' do
129
+ expect(render).to eq "Β· one\n\n Β· sub\n \n\nΒ· two\n\n"
130
+ end
131
+ end
132
+ end
133
+
134
+ describe 'links' do
135
+ let(:md) { "[click](https://example.com)\n" }
136
+ it 'emits OSC 8 hyperlink' do
137
+ expect(render).to eq "\e]8;;https://example.com\e\\click\e]8;;\e\\\n"
138
+ end
139
+ end
140
+
141
+ describe 'images' do
142
+ let(:md) { "![kitten](kitten.jpg)\n" }
143
+ it 'prepends emoji and emits OSC 8 hyperlink' do
144
+ expect(render).to eq "\e]8;;kitten.jpg\e\\πŸ–Ό kitten\e]8;;\e\\\n"
145
+ end
146
+ end
147
+
148
+ describe 'paragraph' do
149
+ context 'plain text' do
150
+ let(:md) { "Just a paragraph.\n" }
151
+ it 'outputs verbatim with trailing newline' do
152
+ expect(render).to eq "Just a paragraph.\n"
153
+ end
154
+ end
155
+ end
156
+ end
data/spec/spec_helper.rb CHANGED
@@ -7,6 +7,102 @@ 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
76
+
77
+ # A module that provides functionality for protecting environment variables
78
+ # during tests.
79
+ #
80
+ # This module ensures that environment variable changes made during test
81
+ # execution are automatically restored to their original values after the test
82
+ # completes. It is designed to prevent side effects between tests that modify
83
+ # environment variables, maintaining a clean testing environment.
84
+ module ProtectEnvVars
85
+ # The apply method creates a lambda that protects environment variables
86
+ # during test execution.
87
+ #
88
+ # @return [Proc] a lambda that wraps test execution with environment variable
89
+ # preservation
90
+ def self.apply
91
+ -> example do
92
+ if example.metadata[:protect_env]
93
+ begin
94
+ stored_env = ENV.to_h
95
+ example.run
96
+ ensure
97
+ ENV.replace(stored_env)
98
+ end
99
+ else
100
+ example.run
101
+ end
102
+ end
103
+ end
104
+ end
105
+
106
+ RSpec.configure do |config|
107
+ config.around(&ProtectEnvVars.apply)
108
+ end
data/tmp/.gitkeep ADDED
File without changes
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.1
4
+ version: 0.6.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.17.0
18
+ version: 2.20.1
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.17.0
25
+ version: 2.20.1
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: all_images
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -113,14 +113,28 @@ dependencies:
113
113
  requirements:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
- version: '3.0'
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: '3.0'
123
+ version: '4.0'
124
+ - !ruby/object:Gem::Dependency
125
+ name: tins
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: '1.61'
131
+ type: :runtime
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: '1.61'
124
138
  - !ruby/object:Gem::Dependency
125
139
  name: json
126
140
  requirement: !ruby/object:Gem::Requirement
@@ -135,6 +149,20 @@ dependencies:
135
149
  - - "~>"
136
150
  - !ruby/object:Gem::Version
137
151
  version: '2.0'
152
+ - !ruby/object:Gem::Dependency
153
+ name: unicode-display_width
154
+ requirement: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - "~>"
157
+ - !ruby/object:Gem::Version
158
+ version: '3.0'
159
+ type: :runtime
160
+ prerelease: false
161
+ version_requirements: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - "~>"
164
+ - !ruby/object:Gem::Version
165
+ version: '3.0'
138
166
  description: |
139
167
  Kramdown::ANSI: A library for rendering Markdown(ish) documents with
140
168
  beautiful ANSI escape sequences in the terminal.
@@ -151,6 +179,7 @@ extra_rdoc_files:
151
179
  - lib/kramdown/ansi/width.rb
152
180
  - lib/kramdown/version.rb
153
181
  files:
182
+ - ".utilsrc"
154
183
  - CHANGES.md
155
184
  - Gemfile
156
185
  - LICENSE
@@ -167,12 +196,20 @@ files:
167
196
  - lib/kramdown/ansi/width.rb
168
197
  - lib/kramdown/version.rb
169
198
  - spec/assets/README.ansi
199
+ - spec/assets/html.ansi
200
+ - spec/assets/html.md
170
201
  - spec/assets/kitten.jpg
202
+ - spec/assets/tables.ansi
203
+ - spec/assets/tables.md
171
204
  - spec/kramdown/ansi/pager_spec.rb
172
205
  - spec/kramdown/ansi/styles_spec.rb
173
206
  - spec/kramdown/ansi/width_spec.rb
207
+ - spec/kramdown/ansi_golden_spec.rb
174
208
  - spec/kramdown/ansi_spec.rb
209
+ - spec/kramdown/ansi_table_spec.rb
210
+ - spec/kramdown/render_spec.rb
175
211
  - spec/spec_helper.rb
212
+ - tmp/.gitkeep
176
213
  homepage: https://github.com/flori/kramdown-ansi
177
214
  licenses:
178
215
  - MIT
@@ -195,12 +232,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
195
232
  - !ruby/object:Gem::Version
196
233
  version: '0'
197
234
  requirements: []
198
- rubygems_version: 4.0.3
235
+ rubygems_version: 4.0.22
199
236
  specification_version: 4
200
237
  summary: Output markdown in the terminal with ANSI escape sequences
201
238
  test_files:
202
239
  - spec/kramdown/ansi/pager_spec.rb
203
240
  - spec/kramdown/ansi/styles_spec.rb
204
241
  - spec/kramdown/ansi/width_spec.rb
242
+ - spec/kramdown/ansi_golden_spec.rb
205
243
  - spec/kramdown/ansi_spec.rb
244
+ - spec/kramdown/ansi_table_spec.rb
245
+ - spec/kramdown/render_spec.rb
206
246
  - spec/spec_helper.rb