Class: Kramdown::Converter::Commonmark

Inherits:
Kramdown
  • Object
show all
Defined in:
lib/kramdown/converter/commonmark.rb

Overview

Overrides the base Kramdown converter to add any special behaviour for CommonMark.

Currently we support an option ‘html_tables` that outputs an HTML table instead of a Markdown table. This is to support possibly being given complex tables, such as from ADF.

Note: this is only an initial implementation. Currently don’t strip out IALs or other specific kramdown syntax.

Constant Summary collapse

END_OF_BLOCK =

replaces the ^ used in kramdown. This forces the current block to end, so that a different list or codeblock can be started. kramdown.gettalong.org/syntax.html#eob-marker

'<!-- -->'

Instance Method Summary collapse

Instance Method Details

#convert(el, opts = { indent: 0 }) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/kramdown/converter/commonmark.rb', line 20

def convert(el, opts = { indent: 0 })
  res = super

  if [:ul, :dl, :ol, :codeblock].include?(el.type) && opts[:next] &&
      ([el.type, :codeblock].include?(opts[:next].type) ||
        (opts[:next].type == :blank && opts[:nnext] &&
          [el.type, :codeblock].include?(opts[:nnext].type)))
    # replace the end of block character
    res.sub!(/\^\n\n\z/m, "#{END_OF_BLOCK}\n\n")
  end

  res
end

#convert_codeblock(el, _opts) ⇒ Object



34
35
36
37
38
39
# File 'lib/kramdown/converter/commonmark.rb', line 34

def convert_codeblock(el, _opts)
  # Although tildes are supported in CommonMark, backticks are more common
  "```#{el.options[:lang]}\n" +
    el.value.split("\n").map { |l| l.empty? ? "" : "#{l}" }.join("\n") +
    "\n```\n\n"
end

#convert_li(el, opts) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/kramdown/converter/commonmark.rb', line 41

def convert_li(el, opts)
  res = super

  if el.children.first && el.children.first.type == :p && !el.children.first.options[:transparent]
    if el.children.size == 1 && @stack.last.children.last == el &&
        (@stack.last.children.any? { |c| c.children.first.type != :p } || @stack.last.children.size == 1)
      # replace the end of block character
      res.sub!(/\^\n\z/m, "#{END_OF_BLOCK}\n")
    end
  end

  res
end

#convert_table(el, opts) ⇒ Object



55
56
57
58
59
60
61
62
# File 'lib/kramdown/converter/commonmark.rb', line 55

def convert_table(el, opts)
  return super unless @options[:html_tables]

  opts[:alignment] = el.options[:alignment]
  result = inner(el, opts)

  "<table>\n#{result}</table>\n\n"
end

#convert_tbody(el, opts) ⇒ Object



70
71
72
73
74
# File 'lib/kramdown/converter/commonmark.rb', line 70

def convert_tbody(el, opts)
  return super unless @options[:html_tables]

  "<tbody>\n#{inner(el, opts)}</tbody>\n"
end

#convert_td(el, opts) ⇒ Object



88
89
90
91
92
93
94
95
96
# File 'lib/kramdown/converter/commonmark.rb', line 88

def convert_td(el, opts)
  return super unless @options[:html_tables]

  # We need to add two linefeeds in order for any inner text to
  # be processed as markdown.  The HTML block must be "closed",
  # as referenced in the CommonMark spec
  # @see https://spec.commonmark.org/0.29/#html-blocks
  "<td>\n\n#{inner(el, opts)}</td>\n"
end

#convert_tfoot(el, opts) ⇒ Object



76
77
78
79
80
# File 'lib/kramdown/converter/commonmark.rb', line 76

def convert_tfoot(el, opts)
  return super unless @options[:html_tables]

  "<tfoot>\n#{inner(el, opts)}</tfoot>\n"
end

#convert_th(el, opts) ⇒ Object



98
99
100
101
102
103
104
105
106
# File 'lib/kramdown/converter/commonmark.rb', line 98

def convert_th(el, opts)
  return super unless @options[:html_tables]

  # We need to add two linefeeds in order for any inner text to
  # be processed as markdown.  The HTML block must be "closed",
  # as referenced in the CommonMark spec
  # @see https://spec.commonmark.org/0.29/#html-blocks
  "<th>\n\n#{inner(el, opts)}</th>\n"
end

#convert_thead(el, opts) ⇒ Object



64
65
66
67
68
# File 'lib/kramdown/converter/commonmark.rb', line 64

def convert_thead(el, opts)
  return super unless @options[:html_tables]

  "<thead>\n#{inner(el, opts)}</thead>\n"
end

#convert_tr(el, opts) ⇒ Object



82
83
84
85
86
# File 'lib/kramdown/converter/commonmark.rb', line 82

def convert_tr(el, opts)
  return super unless @options[:html_tables]

  "<tr>\n#{el.children.map { |c| convert(c, opts) }.join}</tr>\n"
end