kramdown-ansi 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 7249444853b46b626b782ea417e62827627ba0d1da6f54cc8801f8459839f775
4
+ data.tar.gz: 75884f2bf3c0e3b06e71c28f9f4775315745b76ab9cf0d73ec57e49829cd7f6f
5
+ SHA512:
6
+ metadata.gz: 10c992685654c67686a24e4a323ab04619d8957faa61a119569e16dbdb82119278b2756b3cf8d3ba921f7343997d12ddb6632fc8fc3379b00be844862e730d4a
7
+ data.tar.gz: d3342cdf38698f5f59035b0a06dff0341a3fc66127d4de3fd7de46d25d55831175a087f6375fb2052f5e10ff1aabb026026361ab3e73f9a87329b19f3be2d05d
data/CHANGES.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changes
2
+
3
+ ## 2024-10-31 v0.0.0
4
+
5
+ * Start
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # vim: set filetype=ruby et sw=2 ts=2:
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright Florian Frank
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
4
+ this software and associated documentation files (the “Software”), to deal in
5
+ the Software without restriction, including without limitation the rights to
6
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
7
+ of the Software, and to permit persons to whom the Software is furnished to do
8
+ so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,108 @@
1
+ # Kramdown ANSI - Output markdown with ANSI
2
+
3
+ ## Description
4
+
5
+ Kramdown::ANSI: A library for rendering Markdown(ish) documents with beautiful
6
+ ANSI escape sequences in the terminal.
7
+
8
+ ## Installation (gem & bundler)
9
+
10
+ To install Kramdown::ANSI, you can use the following methods:
11
+
12
+ 1. Type
13
+
14
+ ```shell
15
+ gem install kramdown-ansi
16
+ ```
17
+
18
+ in your terminal.
19
+
20
+ 1. Or add the line
21
+
22
+ ```ruby
23
+ gem 'kramdown-ansi'
24
+ ```
25
+
26
+ to your Gemfile and run `bundle install` in your terminal.
27
+
28
+ ## Usage
29
+
30
+ In your own software the library can be used as shown in this example:
31
+
32
+ ```ruby
33
+ require 'kramdown/ansi'
34
+
35
+ puts Kramdown::ANSI.parse(markdown)
36
+ ```
37
+
38
+ ## Executables
39
+
40
+ | Method | Description |
41
+ | :----- | :---------- |
42
+ | `md` executable | Outputs Markdown files with ANSI escape sequences in the terminal |
43
+ | `git-md` executable | A Git plugin that outputs Markdown formatted git commit messages into the terminal |
44
+
45
+ ### The md executable
46
+
47
+ The `md` executable can by used with file arguments:
48
+
49
+ ```shell
50
+ md Foo.md Bar.md …
51
+ ```
52
+
53
+ or as a unix filter:
54
+
55
+ ```shell
56
+ cat Foo.md Bar.md | md
57
+ ```
58
+
59
+ It outputs the markdown files with ANSI escape sequences in the terminal. If
60
+ the file has more lines than the current terminal window has, it attempts to
61
+ open a pager command like `less` or `more` and pipes its output into it.
62
+ By setting the `PAGER` environment variable accordingly one can define a custom
63
+ command for this purpose.
64
+
65
+ ### The git-md executable
66
+
67
+ The `git-md` executable is a git plugin that can be used to output markdown
68
+ formatted git commit messages (just like `git log`) into the terminal using
69
+
70
+ ```shell
71
+ git md
72
+ ```
73
+
74
+ You can pass arguments to it like you would of `git log`, e.g.
75
+
76
+ ```shell
77
+ git md -p
78
+ ```
79
+
80
+ to show the patches additionally to the log messages.
81
+
82
+ By setting the `GIT_PAGER` or `PAGER` environment variable accordingly one can
83
+ define a custom command for this purpose as well, unless a different
84
+ pager command was defined setting `git config set core.pager FOO`, in which
85
+ case the FOO command is used as a pager for all git commands including `git
86
+ md`.
87
+
88
+ ## Download
89
+
90
+ The homepage of this library is located at
91
+
92
+ * https://github.com/flori/kramdown-ansi
93
+
94
+ ## Author
95
+
96
+ <b>Kramdown ANSI</b> was written by Florian Frank [Florian Frank](mailto:flori@ping.de)
97
+
98
+ ## License
99
+
100
+ This software is licensed under the <i>MIT</i> license.
101
+
102
+ ## Mandatory Kitten Image
103
+
104
+ ![cat](spec/assets/kitten.jpg)
105
+
106
+ ---
107
+
108
+ This is the end.
data/Rakefile ADDED
@@ -0,0 +1,40 @@
1
+ # vim: set filetype=ruby et sw=2 ts=2:
2
+
3
+ require 'gem_hadar'
4
+
5
+ GemHadar do
6
+ name 'kramdown-ansi'
7
+ path_name 'kramdown'
8
+ module_type :module
9
+ author 'Florian Frank'
10
+ email 'flori@ping.de'
11
+ homepage "https://github.com/flori/#{name}"
12
+ summary 'Output markdown in the terminal with ANSI escape sequences'
13
+ description <<~EOT
14
+ Kramdown::ANSI: A library for rendering Markdown(ish) documents with
15
+ beautiful ANSI escape sequences in the terminal.
16
+ EOT
17
+ test_dir 'spec'
18
+ ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.AppleDouble', '.bundle',
19
+ '.yardoc', 'doc', 'tags', 'errors.lst', 'cscope.out', 'coverage', 'tmp',
20
+ 'yard'
21
+ package_ignore '.all_images.yml', '.tool-versions', '.gitignore', 'VERSION',
22
+ '.rspec', *Dir.glob('.github/**/*', File::FNM_DOTMATCH)
23
+ readme 'README.md'
24
+
25
+ executables << 'md' << 'git-md'
26
+
27
+ required_ruby_version '~> 3.1'
28
+
29
+ dependency 'term-ansicolor', '~> 1.11'
30
+ dependency 'kramdown-parser-gfm', '~> 1.1'
31
+ dependency 'terminal-table', '~> 3.0'
32
+ development_dependency 'all_images', '~> 0.4'
33
+ development_dependency 'rspec', '~> 3.2'
34
+ development_dependency 'debug'
35
+ development_dependency 'simplecov'
36
+
37
+ licenses << 'MIT'
38
+
39
+ clobber 'coverage'
40
+ end
data/bin/git-md ADDED
@@ -0,0 +1,48 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'kramdown/ansi'
4
+ include Term::ANSIColor
5
+ require 'shellwords'
6
+
7
+ cmd = %{git log --color=always --pretty=format:"commit %H%C(auto)%d%nDate: %Cgreen%cD (%cr)%Creset%nAuthor: %Cblue%an <%ae>%Creset%n%nMARKUP%n%s%n%n%b%nMARKDOWN%n"}
8
+
9
+ core_pager = `git config get core.pager`.chomp.full?
10
+ git_pager = ENV['GIT_PAGER'].full?
11
+ default_pager = ENV['PAGER'].full?
12
+ if fallback_pager = `which less`.chomp.full? || `which more`.chomp.full?
13
+ fallback_pager << ' -r'
14
+ end
15
+ my_pager = git_pager || core_pager || default_pager || fallback_pager
16
+
17
+ repo_url = case git_origin_url = `git remote get-url origin`.chomp
18
+ when %r(\Ahttps://)
19
+ u = git_origin_url.sub(%r(\.git\z), '')
20
+ u << '/commit/'
21
+ when %r(\Agit@github.com:([^.]+))
22
+ "https://github.com/#$1/commit/"
23
+ end
24
+
25
+ Kramdown::ANSI::Pager.pager(command: my_pager) do |output|
26
+ IO.popen("#{cmd} #{Shellwords.join(ARGV)}") do |log|
27
+ until log.eof?
28
+ message = nil
29
+ log.each do |line|
30
+ case line
31
+ when /^MARKUP$/
32
+ message = ''
33
+ when /^MARKDOWN$/
34
+ output.puts Kramdown::ANSI.parse(message + "\n---\n")
35
+ message = nil
36
+ else
37
+ if message
38
+ message << line
39
+ else
40
+ output.puts line.sub(/(?<=^commit )(\h{40})/) {
41
+ yellow { repo_url ? hyperlink(repo_url + $1) { $1 } : $1 }
42
+ }
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
data/bin/md ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'kramdown/ansi'
4
+
5
+ rendered = Kramdown::ANSI.parse(ARGF.read)
6
+ default_pager = ENV['PAGER'].full?
7
+ if fallback_pager = `which less`.chomp.full? || `which more`.chomp.full?
8
+ fallback_pager << ' -r'
9
+ end
10
+ my_pager = default_pager || fallback_pager
11
+
12
+ Kramdown::ANSI::Pager.pager(lines: rendered.count(?\n), command: my_pager) do |output|
13
+ output.puts rendered
14
+ end
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ # stub: kramdown-ansi 0.0.0 ruby lib
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "kramdown-ansi".freeze
6
+ s.version = "0.0.0".freeze
7
+
8
+ s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
+ s.require_paths = ["lib".freeze]
10
+ s.authors = ["Florian Frank".freeze]
11
+ s.date = "2024-10-31"
12
+ s.description = "Kramdown::ANSI: A library for rendering Markdown(ish) documents with\nbeautiful ANSI escape sequences in the terminal.\n".freeze
13
+ s.email = "flori@ping.de".freeze
14
+ s.executables = ["md".freeze, "git-md".freeze]
15
+ s.extra_rdoc_files = ["README.md".freeze, "lib/kramdown/ansi.rb".freeze, "lib/kramdown/ansi/pager.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, "kramdown-ansi.gemspec".freeze, "lib/kramdown/ansi.rb".freeze, "lib/kramdown/ansi/pager.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/width_spec.rb".freeze, "spec/kramdown/ansi_spec.rb".freeze, "spec/spec_helper.rb".freeze]
17
+ s.homepage = "https://github.com/flori/kramdown-ansi".freeze
18
+ s.licenses = ["MIT".freeze]
19
+ s.rdoc_options = ["--title".freeze, "Kramdown-ansi - Output markdown in the terminal with ANSI escape sequences".freeze, "--main".freeze, "README.md".freeze]
20
+ s.required_ruby_version = Gem::Requirement.new("~> 3.1".freeze)
21
+ s.rubygems_version = "3.5.22".freeze
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/width_spec.rb".freeze, "spec/kramdown/ansi_spec.rb".freeze, "spec/spec_helper.rb".freeze]
24
+
25
+ s.specification_version = 4
26
+
27
+ s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.19".freeze])
28
+ s.add_development_dependency(%q<all_images>.freeze, ["~> 0.4".freeze])
29
+ s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2".freeze])
30
+ s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
31
+ s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
32
+ s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
33
+ s.add_runtime_dependency(%q<kramdown-parser-gfm>.freeze, ["~> 1.1".freeze])
34
+ s.add_runtime_dependency(%q<terminal-table>.freeze, ["~> 3.0".freeze])
35
+ end
@@ -0,0 +1,37 @@
1
+ require 'tins/terminal'
2
+
3
+ module Kramdown::ANSI::Pager
4
+ module_function
5
+
6
+ # If called without a block returns either the provided command for paging if
7
+ # the given number of lines are exceeding the available number of terminal
8
+ # lines or nil. If a block was provided it yields to an IO handle for the
9
+ # pager command in the latter case or STDOUT in the former.
10
+ #
11
+ # @param command [String] the pager command (optional)
12
+ # @param lines [Integer] the number of lines in the output (optional)
13
+ # @yield [IO] yields the output IO handle for further processing
14
+ # @return [NilClass] returns nil if STDOUT is used or STDOUT is not a TTY.
15
+ def pager(command: nil, lines: nil, &block)
16
+ if block
17
+ if my_pager = pager(command:, lines:)
18
+ IO.popen(my_pager, 'w') do |output|
19
+ output.sync = true
20
+ yield output
21
+ output.close
22
+ end
23
+ else
24
+ yield STDOUT
25
+ end
26
+ else
27
+ return unless STDOUT.tty?
28
+ if lines
29
+ if lines >= Tins::Terminal.lines
30
+ pager(command:)
31
+ end
32
+ else
33
+ command
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,61 @@
1
+ require 'tins/terminal'
2
+ require 'term/ansicolor'
3
+
4
+ module Kramdown::ANSI::Width
5
+ include Term::ANSIColor
6
+ extend Term::ANSIColor
7
+
8
+ module_function
9
+
10
+ # Returns the width of the terminal in characters, given a percentage.
11
+ #
12
+ # @param percentage [Numeric] the percentage value (defaults to 100.0)
13
+ # @return [Integer] the calculated width
14
+ def width(percentage: 100.0)
15
+ ((Float(percentage) * Tins::Terminal.columns) / 100).floor
16
+ end
17
+
18
+ # Wraps text to a specified width.
19
+ #
20
+ # @param text [String] the text to wrap
21
+ # @option percentage [Numeric] the percentage value for the width (defaults to nil)
22
+ # @option length [Integer] the character length for the width (defaults to nil)
23
+ # @return [String] the wrapped text
24
+ # @raise [ArgumentError] if neither `percentage` nor `length` is provided
25
+ def wrap(text, percentage: nil, length: nil)
26
+ percentage.nil? ^ length.nil? or
27
+ raise ArgumentError, "either pass percentage or length argument"
28
+ percentage and length ||= width(percentage:)
29
+ text.gsub(/(?<!\n)\n(?!\n)/, ' ').lines.map do |line|
30
+ if length >= 1 && uncolor { line }.length > length
31
+ line.gsub(/(.{1,#{length}})(\s+|$)/, "\\1\n").strip
32
+ else
33
+ line.strip
34
+ end
35
+ end * ?\n
36
+ end
37
+
38
+ # Truncates a given string to a specified length or percentage. If the text
39
+ # is longer an ellipsis sequence is added at the end of the generated string,
40
+ # to indicate that a truncation has been performed.
41
+ #
42
+ # @param text [String] the input string to truncate
43
+ # @option percentage [Numeric] the percentage value for the width (defaults to nil)
44
+ # @option length [Integer] the character length for the width (defaults to nil)
45
+ # @option ellipsis [Character] the truncation indicator (defaults to ?…)
46
+ # @return [String] the truncated string
47
+ # @raise [ArgumentError] if neither `percentage` nor `length` is provided
48
+ def truncate(text, percentage: nil, length: nil, ellipsis: ?…)
49
+ percentage.nil? ^ length.nil? or
50
+ raise ArgumentError, "either pass percentage or length argument"
51
+ percentage and length ||= width(percentage:)
52
+ ellipsis_length = ellipsis.size
53
+ if length < ellipsis_length
54
+ +''
55
+ elsif text.size >= length + ellipsis_length
56
+ text[0, length - ellipsis_length] + ellipsis
57
+ else
58
+ text
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,224 @@
1
+ require 'kramdown'
2
+ require 'kramdown-parser-gfm'
3
+ require 'terminal-table'
4
+ require 'term/ansicolor'
5
+ module Kramdown
6
+ class Kramdown::ANSI < Kramdown::Converter::Base
7
+ end
8
+ end
9
+ require 'kramdown/ansi/width'
10
+ require 'kramdown/ansi/pager'
11
+
12
+ class Kramdown::ANSI < Kramdown::Converter::Base
13
+ include Term::ANSIColor
14
+ include Kramdown::ANSI::Width
15
+
16
+ class ::Kramdown::Parser::Mygfm < ::Kramdown::Parser::GFM
17
+ def initialize(source, options)
18
+ options[:gfm_quirks] << :no_auto_typographic
19
+ super
20
+ @block_parsers -= %i[
21
+ definition_list block_html block_math
22
+ footnote_definition abbrev_definition
23
+ ]
24
+ @span_parsers -= %i[ footnote_marker inline_math ]
25
+ end
26
+ end
27
+
28
+ def self.parse(source)
29
+ @doc = Kramdown::Document.new(
30
+ source, input: :mygfm, auto_ids: false, entity_output: :as_char
31
+ ).to_ansi
32
+ end
33
+
34
+ def initialize(root, options)
35
+ super
36
+ end
37
+
38
+ def convert(el, opts = {})
39
+ send("convert_#{el.type}", el, opts)
40
+ end
41
+
42
+ def inner(el, opts, &block)
43
+ result = +''
44
+ options = opts.dup.merge(parent: el)
45
+ el.children.each_with_index do |inner_el, index|
46
+ options[:index] = index
47
+ options[:result] = result
48
+ begin
49
+ content = send("convert_#{inner_el.type}", inner_el, options)
50
+ result << (block&.(inner_el, index, content) || content)
51
+ rescue NameError => e
52
+ warning "Caught #{e.class} for #{inner_el.type}"
53
+ end
54
+ end
55
+ result
56
+ end
57
+
58
+ def convert_root(el, opts)
59
+ inner(el, opts)
60
+ end
61
+
62
+ def convert_blank(_el, opts)
63
+ opts[:result] =~ /\n\n\Z|\A\Z/ ? "" : "\n"
64
+ end
65
+
66
+ def convert_text(el, _opts)
67
+ el.value
68
+ end
69
+
70
+ def convert_header(el, opts)
71
+ newline bold { underline { inner(el, opts) } }
72
+ end
73
+
74
+ def convert_p(el, opts)
75
+ length = width(percentage: 90) - opts[:list_indent].to_i
76
+ length < 0 and return ''
77
+ newline wrap(inner(el, opts), length:)
78
+ end
79
+
80
+ def convert_strong(el, opts)
81
+ bold { inner(el, opts) }
82
+ end
83
+
84
+ def convert_em(el, opts)
85
+ italic { inner(el, opts) }
86
+ end
87
+
88
+ def convert_a(el, opts)
89
+ url = el.attr['href']
90
+ hyperlink(url) { inner(el, opts) }
91
+ end
92
+
93
+ def convert_codespan(el, _opts)
94
+ blue { el.value }
95
+ end
96
+
97
+ def convert_codeblock(el, _opts)
98
+ blue { el.value }
99
+ end
100
+
101
+ def convert_blockquote(el, opts)
102
+ newline ?“ + inner(el, opts).sub(/\n+\z/, '') + ?”
103
+ end
104
+
105
+ def convert_hr(_el, _opts)
106
+ newline ?─ * width(percentage: 100)
107
+ end
108
+
109
+ def convert_img(el, _opts)
110
+ url = el.attr['src']
111
+ alt = el.attr['alt']
112
+ alt.strip.size == 0 and alt = url
113
+ alt = '🖼 ' + alt
114
+ hyperlink(url) { alt }
115
+ end
116
+
117
+ def convert_ul(el, opts)
118
+ list_indent = opts[:list_indent].to_i
119
+ inner(el, opts) { |_inner_el, index, content|
120
+ result = '· %s' % content
121
+ result = newline(result, count: index <= el.children.size - 1 ? 1 : 2)
122
+ result.gsub(/^/, ' ' * list_indent)
123
+ }
124
+ end
125
+
126
+ def convert_ol(el, opts)
127
+ list_indent = opts[:list_indent].to_i
128
+ inner(el, opts) { |_inner_el, index, content|
129
+ result = '%u. %s' % [ index + 1, content ]
130
+ result = newline(result, count: index <= el.children.size - 1 ? 1 : 2)
131
+ result.gsub(/^/, ' ' * list_indent)
132
+ }
133
+ end
134
+
135
+ def convert_li(el, opts)
136
+ opts = opts.dup
137
+ opts[:list_indent] = 2 + opts[:list_indent].to_i
138
+ newline inner(el, opts).sub(/\n+\Z/, '')
139
+ end
140
+
141
+ def convert_html_element(el, opts)
142
+ if el.value == 'i' || el.value == 'em'
143
+ italic { inner(el, opts) }
144
+ elsif el.value == 'b' || el.value == 'strong'
145
+ bold { inner(el, opts) }
146
+ else
147
+ ''
148
+ end
149
+ end
150
+
151
+ def convert_table(el, opts)
152
+ table = Terminal::Table.new
153
+ table.style = {
154
+ all_separators: true,
155
+ border: :unicode_round,
156
+ }
157
+ opts[:table] = table
158
+ inner(el, opts)
159
+ el.options[:alignment].each_with_index do |a, i|
160
+ a == :default and next
161
+ opts[:table].align_column(i, a)
162
+ end
163
+ newline table.to_s
164
+ end
165
+
166
+ def convert_thead(el, opts)
167
+ rows = inner(el, opts)
168
+ rows = rows.split(/\s*\|\s*/)[1..].map(&:strip)
169
+ opts[:table].headings = rows
170
+ ''
171
+ end
172
+
173
+ def convert_tbody(el, opts)
174
+ res = +''
175
+ res << inner(el, opts)
176
+ end
177
+
178
+ def convert_tfoot(el, opts)
179
+ ''
180
+ end
181
+
182
+ def convert_tr(el, opts)
183
+ return '' if el.children.empty?
184
+ full_width = width(percentage: 90)
185
+ cols = el.children.map { |c| convert(c, opts).strip }
186
+ row_size = cols.sum(&:size)
187
+ return '' if row_size.zero?
188
+ opts[:table] << cols.map { |c|
189
+ length = (full_width * (c.size / row_size.to_f)).floor
190
+ wrap(c, length:)
191
+ }
192
+ ''
193
+ end
194
+
195
+ def convert_td(el, opts)
196
+ inner(el, opts)
197
+ end
198
+
199
+ def convert_entity(el, _opts)
200
+ el.value.char
201
+ end
202
+
203
+ def convert_xml_comment(*)
204
+ ''
205
+ end
206
+
207
+ def convert_xml_pi(*)
208
+ ''
209
+ end
210
+
211
+ def convert_br(_el, opts)
212
+ ''
213
+ end
214
+
215
+ def convert_smart_quote(el, _opts)
216
+ el.value.to_s =~ /[rl]dquo/ ? "\"" : "'"
217
+ end
218
+
219
+ def newline(text, count: 1)
220
+ text.gsub(/\n*\z/, ?\n * count)
221
+ end
222
+ end
223
+
224
+ Kramdown::Converter.const_set(:Ansi, Kramdown::ANSI)
@@ -0,0 +1,8 @@
1
+ module Kramdown
2
+ # Kramdown version
3
+ VERSION = '0.0.0'
4
+ VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
+ VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
+ VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
7
+ VERSION_BUILD = VERSION_ARRAY[2] # :nodoc:
8
+ end