Class: Kramdown::ANSI

Inherits:
Converter::Base
  • Object
show all
Includes:
Width
Defined in:
lib/kramdown/ansi.rb,
lib/kramdown/ansi.rb

Overview

A converter class that transforms Kramdown documents into ANSI-formatted terminal output.

The Kramdown::ANSI class extends Kramdown::Converter::Base to provide functionality for rendering Markdown documents with ANSI escape sequences for terminal display. It handles various Markdown elements such as headers, paragraphs, lists, and code blocks, applying configurable ANSI styles to enhance the visual presentation in terminals.

Examples:

Converting a markdown string to ANSI formatted output

ansi_output = Kramdown::ANSI.parse(markdown_string)

Using custom ANSI styles

styles = { header: [:bold, :underline], code: :red }
ansi_output = Kramdown::ANSI.parse(markdown_string, ansi_styles: styles)

Defined Under Namespace

Modules: Pager, Width Classes: Styles

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Width

truncate, width, wrap

Constructor Details

#initialize(root, options) ⇒ void

Initializes a new Kramdown::ANSI converter instance with optional ANSI styling configuration.

Parameters:

  • root (Kramdown::Element)

    the root element of the document to convert

  • options (Hash)

    additional options for the conversion process



103
104
105
106
# File 'lib/kramdown/ansi.rb', line 103

def initialize(root, options)
  @ansi_styles = Kramdown::ANSI::Styles.new.configure(options.delete(:ansi_styles))
  super
end

Class Method Details

.parse(source, options = {}) ⇒ String

Parses the given markdown source into ANSI formatted terminal output.

Parameters:

  • source (String)

    the markdown content to be converted

  • options (Hash) (defaults to: {})

    additional options for the parsing process

Returns:

  • (String)

    the ANSI formatted terminal output



90
91
92
93
94
95
# File 'lib/kramdown/ansi.rb', line 90

def self.parse(source, options = {})
  options = { input: :mygfm, auto_ids: false, entity_output: :as_char }.merge(
    options.transform_keys(&:to_sym)
  )
  @doc = Kramdown::Document.new(source, options).to_ansi
end

Instance Method Details

#convert(el, opts = {}) ⇒ String

The convert method dispatches to type-specific conversion methods based on the element’s type.

Parameters:

  • el (Kramdown::Element)

    the element to convert

  • opts (Hash) (defaults to: {})

    additional options for the conversion process

Returns:

  • (String)

    the converted content of the element



114
115
116
# File 'lib/kramdown/ansi.rb', line 114

def convert(el, opts = {})
  send("convert_#{el.type}", el, opts)
end

#convert_a(el, opts) ⇒ String

The convert_a method processes an anchor element by applying hyperlink formatting to its content.

Parameters:

  • el (Kramdown::Element)

    the anchor element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the hyperlink formatted content



231
232
233
234
# File 'lib/kramdown/ansi.rb', line 231

def convert_a(el, opts)
  url = el.attr['href']
  hyperlink(url) { inner(el, opts) }
end

#convert_blank(_el, opts) ⇒ String

The convert_blank method handles blank line conversion in Markdown documents.

This method determines whether a blank element should produce output based on the context of the surrounding content. It checks if the current result ends with double newlines or is empty, and returns an appropriate newline character to maintain proper spacing in the rendered output.

Parameters:

  • _el (Kramdown::Element)

    the blank element being converted (unused)

  • opts (Hash)

    conversion options containing the result context

Returns:

  • (String)

    either an empty string or a single newline character



169
170
171
# File 'lib/kramdown/ansi.rb', line 169

def convert_blank(_el, opts)
  opts[:result] =~ /\n\n\Z|\A\Z/ ? "" : "\n"
end

#convert_blockquote(el, opts) ⇒ String

The convert_blockquote method processes a blockquote element by applying proper formatting.

This method takes a blockquote element and formats its content with quotation marks while ensuring appropriate newline handling. It delegates the inner content processing to the inner method and then wraps the result with quotation marks.

proper newlines

Parameters:

  • el (Kramdown::Element)

    the blockquote element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the formatted blockquote content with quotation marks and



268
269
270
# File 'lib/kramdown/ansi.rb', line 268

def convert_blockquote(el, opts)
  newline ?“ + inner(el, opts).sub(/\n+\z/, '') + ?”
end

#convert_br(_el, opts) ⇒ String

The convert_br method handles the conversion of line break elements.

This method processes HTML line break elements (br tags) by returning an empty string, effectively ignoring them during the ANSI terminal output conversion process. It is part of the Kramdown::ANSI converter’s element handling suite.

during conversion

Parameters:

  • _el (Kramdown::Element)

    the line break element being converted (unused)

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    an empty string to indicate that line breaks are ignored



532
533
534
# File 'lib/kramdown/ansi.rb', line 532

def convert_br(_el, opts)
  ''
end

#convert_codeblock(el, _opts) ⇒ String

The convert_codeblock method processes a code block element by applying ANSI styling to its content.

Parameters:

  • el (Kramdown::Element)

    the code block element to convert

  • _opts (Hash)

    additional options (unused)

Returns:

  • (String)

    the styled code block content



252
253
254
# File 'lib/kramdown/ansi.rb', line 252

def convert_codeblock(el, _opts)
  apply_style(:code) { el.value }
end

#convert_codespan(el, _opts) ⇒ String

The convert_codespan method processes a code span element by applying ANSI styling to its content.

Parameters:

  • el (Kramdown::Element)

    the code span element to convert

  • _opts (Hash)

    additional options (unused)

Returns:

  • (String)

    the styled code span content



242
243
244
# File 'lib/kramdown/ansi.rb', line 242

def convert_codespan(el, _opts)
  apply_style(:code) { el.value }
end

#convert_em(el, opts) ⇒ String

The convert_em method processes an emphasis element by applying ANSI styling to its content.

Parameters:

  • el (Kramdown::Element)

    the emphasis element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the styled emphasis content



221
222
223
# File 'lib/kramdown/ansi.rb', line 221

def convert_em(el, opts)
  apply_style(:em) { inner(el, opts) }
end

#convert_entity(el, _opts) ⇒ String

The convert_entity method processes an entity element by extracting its character value.

Parameters:

  • el (Kramdown::Element)

    the entity element to convert

  • _opts (Hash)

    additional options (unused)

Returns:

  • (String)

    the character representation of the entity



487
488
489
# File 'lib/kramdown/ansi.rb', line 487

def convert_entity(el, _opts)
  el.value.char
end

#convert_header(el, opts) ⇒ String

The convert_header method processes a header element by applying ANSI styling and adding a newline.

Parameters:

  • el (Kramdown::Element)

    the header element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the styled header content with a trailing newline



188
189
190
# File 'lib/kramdown/ansi.rb', line 188

def convert_header(el, opts)
  newline apply_style(:header) { inner(el, opts) }
end

#convert_hr(_el, _opts) ⇒ String

The convert_hr method processes a horizontal rule element by generating a full-width separator line.

This method creates a horizontal rule (divider) using the Unicode line-drawing character and applies proper newline formatting to ensure correct spacing in the terminal output.

terminal width with newlines

Parameters:

  • _el (Kramdown::Element)

    the horizontal rule element to convert (unused)

  • _opts (Hash)

    conversion options (unused)

Returns:

  • (String)

    a formatted horizontal rule line spanning the full



283
284
285
# File 'lib/kramdown/ansi.rb', line 283

def convert_hr(_el, _opts)
  newline ?─ * width(percentage: 100)
end

#convert_html_element(el, opts) ⇒ String

The convert_html_element method processes HTML inline elements such as <i>, <em>, <b>, and <strong> by applying the corresponding ANSI styles to their content. It handles emphasis and strong formatting tags specifically, while ignoring other HTML elements by returning an empty string.

empty string for other elements

Parameters:

  • el (Kramdown::Element)

    the HTML element being converted

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the styled content for emphasis or strong elements, or an



371
372
373
374
375
376
377
378
379
# File 'lib/kramdown/ansi.rb', line 371

def convert_html_element(el, opts)
  if el.value == 'i' || el.value == 'em'
    apply_style(:em) { inner(el, opts) }
  elsif el.value == 'b' || el.value == 'strong'
    apply_style(:strong) { inner(el, opts) }
  else
    ''
  end
end

#convert_img(el, _opts) ⇒ String

The convert_img method processes an image element by extracting its source URL and alternative text, formatting the display with a fallback to the URL if the alt text is empty, and applying hyperlink styling.

Parameters:

  • el (Kramdown::Element)

    the image element to convert

  • _opts (Hash)

    additional options (unused)

Returns:

  • (String)

    the formatted image content with hyperlink styling



294
295
296
297
298
299
300
# File 'lib/kramdown/ansi.rb', line 294

def convert_img(el, _opts)
  url = el.attr['src']
  alt = el.attr['alt']
  alt.strip.size == 0 and alt = url
  alt = '🖼 ' + alt
  hyperlink(url) { alt }
end

#convert_li(el, opts) ⇒ String

The convert_li method processes a list item element by applying indentation and handling newlines.

This method takes a list item element and modifies the conversion options to include appropriate indentation for nested lists. It then delegates the inner content processing to the inner method and ensures proper newline handling at the end of the content.

and newlines

Parameters:

  • el (Kramdown::Element)

    the list item element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the formatted list item content with proper indentation



356
357
358
359
360
# File 'lib/kramdown/ansi.rb', line 356

def convert_li(el, opts)
  opts = opts.dup
  opts[:list_indent] = 2 + opts[:list_indent].to_i
  newline inner(el, opts).sub(/\n+\Z/, '')
end

#convert_ol(el, opts) ⇒ String

The convert_ol method processes an ordered list element by applying numbered bullet point formatting and indentation.

This method takes an ordered list element and formats its child elements with sequential numbers, applying appropriate newline handling based on the list item’s position, and adding indentation to align the content properly within the terminal output.

and proper indentation

Parameters:

  • el (Kramdown::Element)

    the ordered list element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the formatted ordered list content with numbered points



335
336
337
338
339
340
341
342
# File 'lib/kramdown/ansi.rb', line 335

def convert_ol(el, opts)
  list_indent = opts[:list_indent].to_i
  inner(el, opts) { |_inner_el, index, content|
    result = '%u. %s' % [ index + 1, content ]
    result = newline(result, count: index <= el.children.size - 1 ? 1 : 2)
    result.gsub(/^/, ' ' * list_indent)
  }
end

#convert_p(el, opts) ⇒ String

The convert_p method processes a paragraph element by calculating the appropriate text width based on the terminal size and list indentation, then wraps the content accordingly.

Parameters:

  • el (Kramdown::Element)

    the paragraph element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the wrapped and formatted paragraph content with proper newlines



199
200
201
202
203
# File 'lib/kramdown/ansi.rb', line 199

def convert_p(el, opts)
  length = width(percentage: 90) - opts[:list_indent].to_i
  length < 0 and return ''
  newline wrap(inner(el, opts), length:)
end

#convert_root(el, opts) ⇒ String

The convert_root method processes the root element of a Kramdown document.

This method serves as the entry point for converting the top-level element of a Markdown document into its ANSI-formatted terminal representation. It delegates the actual processing to the inner method, which handles the recursive conversion of child elements.

Parameters:

  • el (Kramdown::Element)

    the root element to convert

  • opts (Hash)

    additional options for the conversion process

Returns:

  • (String)

    the ANSI formatted content of the root element and its children



154
155
156
# File 'lib/kramdown/ansi.rb', line 154

def convert_root(el, opts)
  inner(el, opts)
end

#convert_smart_quote(el, _opts) ⇒ String

The convert_smart_quote method processes smart quote entities by determining whether to output a double quotation mark or single quotation mark based on the entity’s type.

double quotes, and a single quotation mark for other smart quote entities

Parameters:

  • el (Kramdown::Element)

    the smart quote element being converted

  • _opts (Hash)

    additional options (unused)

Returns:

  • (String)

    a double quotation mark for right double quotes or left



544
545
546
# File 'lib/kramdown/ansi.rb', line 544

def convert_smart_quote(el, _opts)
  el.value.to_s =~ /[rl]dquo/ ? "\"" : "'"
end

#convert_strong(el, opts) ⇒ String

The convert_strong method processes a strong emphasis element by applying ANSI styling to its content.

Parameters:

  • el (Kramdown::Element)

    the strong element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the styled strong content



211
212
213
# File 'lib/kramdown/ansi.rb', line 211

def convert_strong(el, opts)
  apply_style(:strong) { inner(el, opts) }
end

#convert_table(el, opts) ⇒ String

The convert_table method processes a table element by creating a terminal table instance, applying styling and alignment options, and generating formatted output with newlines.

Parameters:

  • el (Kramdown::Element)

    the table element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the formatted table content with proper styling and newlines



388
389
390
391
392
393
394
395
396
397
398
399
400
401
# File 'lib/kramdown/ansi.rb', line 388

def convert_table(el, opts)
  table = Terminal::Table.new
  table.style = {
    all_separators: true,
    border: :unicode_round,
  }
  opts[:table] = table
  inner(el, opts)
  el.options[:alignment].each_with_index do |a, i|
    a == :default and next
    opts[:table].align_column(i, a)
  end
  newline table.to_s
end

#convert_tbody(el, opts) ⇒ String

The convert_tbody method processes a table body element by collecting its inner content.

This method handles the conversion of HTML table body elements, gathering all child elements’ content and returning it as a string. It serves as part of the table conversion process, working in conjunction with other table-related methods to generate properly formatted terminal output.

table body

Parameters:

  • el (Kramdown::Element)

    the table body element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the concatenated content of all child elements within the



430
431
432
433
# File 'lib/kramdown/ansi.rb', line 430

def convert_tbody(el, opts)
  res = +''
  res << inner(el, opts)
end

#convert_td(el, opts) ⇒ String

The convert_td method processes a table data cell element by delegating its content conversion to the inner method.

Parameters:

  • el (Kramdown::Element)

    the table data cell element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the converted content of the table data cell element



477
478
479
# File 'lib/kramdown/ansi.rb', line 477

def convert_td(el, opts)
  inner(el, opts)
end

#convert_text(el, _opts) ⇒ String

The convert_text method processes a text element by extracting its value.

Parameters:

  • el (Kramdown::Element)

    the text element to convert

  • _opts (Hash)

    additional options (unused)

Returns:

  • (String)

    the raw text content of the element



178
179
180
# File 'lib/kramdown/ansi.rb', line 178

def convert_text(el, _opts)
  el.value
end

#convert_tfoot(el, opts) ⇒ String

The convert_tfoot method handles the conversion of table footer elements.

This method processes table footer elements by returning an empty string, effectively ignoring footer content during the ANSI terminal output conversion. It is part of the table conversion process, working alongside other table-related methods to generate properly formatted terminal output.

footer element

Parameters:

  • el (Kramdown::Element)

    the table footer element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    an empty string to indicate successful handling of the



446
447
448
# File 'lib/kramdown/ansi.rb', line 446

def convert_tfoot(el, opts)
  ''
end

#convert_thead(el, opts) ⇒ String

The convert_thead method processes a table header element by extracting and formatting the heading rows from the table content, then assigns them to the terminal table instance.

assignment of headings to the table instance

Parameters:

  • el (Kramdown::Element)

    the table header element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    an empty string to indicate successful processing and



411
412
413
414
415
416
# File 'lib/kramdown/ansi.rb', line 411

def convert_thead(el, opts)
  rows = inner(el, opts)
  rows = rows.split(/\s*\|\s*/)[1..].map(&:strip)
  opts[:table].headings = rows
  ''
end

#convert_tr(el, opts) ⇒ String

The convert_tr method processes a table row element by calculating column widths based on content size, wrapping text to fit within the terminal width, and adding the formatted row to the terminal table instance.

addition of the row to the table instance

Parameters:

  • el (Kramdown::Element)

    the table row element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    an empty string to indicate successful processing and



458
459
460
461
462
463
464
465
466
467
468
469
# File 'lib/kramdown/ansi.rb', line 458

def convert_tr(el, opts)
  return '' if el.children.empty?
  full_width = width(percentage: 90)
  cols = el.children.map { |c| convert(c, opts).strip }
  row_size = cols.sum(&:size)
  return '' if row_size.zero?
  opts[:table] << cols.map { |c|
    length = (full_width * (c.size / row_size.to_f)).floor
    wrap(c, length:)
  }
  ''
end

#convert_ul(el, opts) ⇒ String

The convert_ul method processes an unordered list element by applying bullet point formatting and indentation.

This method takes an unordered list element and formats its child elements with bullet points, applying appropriate newline handling based on the list item’s position, and adding indentation to align the content properly within the terminal output.

and proper indentation

Parameters:

  • el (Kramdown::Element)

    the unordered list element to convert

  • opts (Hash)

    conversion options containing context for processing

Returns:

  • (String)

    the formatted unordered list content with bullet points



314
315
316
317
318
319
320
321
# File 'lib/kramdown/ansi.rb', line 314

def convert_ul(el, opts)
  list_indent = opts[:list_indent].to_i
  inner(el, opts) { |_inner_el, index, content|
    result = '· %s' % content
    result = newline(result, count: index <= el.children.size - 1 ? 1 : 2)
    result.gsub(/^/, ' ' * list_indent)
  }
end

#convert_xml_commentString

The convert_xml_comment method handles XML comment elements by returning an empty string.

This method is part of the Kramdown::ANSI converter and is responsible for processing XML comment elements that appear in the Markdown document. It ignores XML comments during the ANSI terminal output conversion process, returning an empty string to indicate that no content should be rendered for these elements.

during conversion

Returns:

  • (String)

    an empty string to indicate that XML comments are ignored



502
503
504
# File 'lib/kramdown/ansi.rb', line 502

def convert_xml_comment(*)
  ''
end

#convert_xml_piString

The convert_xml_pi method handles the conversion of XML processing instruction elements.

This method is part of the Kramdown::ANSI converter and is responsible for processing XML processing instruction elements that appear in the Markdown document. It ignores these elements during the ANSI terminal output conversion process, returning an empty string to indicate that no content should be rendered for these elements.

instructions are ignored during conversion

Returns:

  • (String)

    an empty string to indicate that XML processing



517
518
519
# File 'lib/kramdown/ansi.rb', line 517

def convert_xml_pi(*)
  ''
end

#inner(el, opts) {|Kramdown::Element, Integer, String| ... } ⇒ String

The inner method processes child elements of a given element and applies optional block processing to each child.

Parameters:

  • el (Kramdown::Element)

    the element whose children will be processed

  • opts (Hash)

    additional options for the processing

Yields:

  • (Kramdown::Element, Integer, String)

    optional block to customize processing of each child element

Yield Parameters:

  • inner_el (Kramdown::Element)

    the current child element being processed

  • index (Integer)

    the index of the current child element

  • content (String)

    the converted content of the current child element

Returns:

  • (String)

    the concatenated result of processing all child elements



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/kramdown/ansi.rb', line 128

def inner(el, opts, &block)
  result = +''
  options = opts.dup.merge(parent: el)
  el.children.each_with_index do |inner_el, index|
    options[:index] = index
    options[:result] = result
    begin
      content = send("convert_#{inner_el.type}", inner_el, options)
      result << (block&.(inner_el, index, content) || content)
    rescue NameError => e
      warning "Caught #{e.class} for #{inner_el.type}"
    end
  end
  result
end

#newline(text, count: 1) ⇒ String

The newline method appends a specified number of newline characters to the end of a given text string.

Parameters:

  • text (String)

    the input text to which newlines will be appended

  • count (Integer) (defaults to: 1)

    the number of newline characters to append (defaults to 1)

Returns:

  • (String)

    the text with the specified number of trailing newline characters



554
555
556
# File 'lib/kramdown/ansi.rb', line 554

def newline(text, count: 1)
  text.gsub(/\n*\z/, ?\n * count)
end