Kramdown::Converter::Latex

Converts an element tree to LaTeX.

This converter uses ideas from other Markdown-to-LaTeX converters like Pandoc and Maruku.

You can customize this converter by sub-classing it and overriding the convert_NAME methods. Each such method takes the following parameters:

el

The element of type NAME to be converted.

opts

A hash containing processing options that are passed down from parent elements. The key :parent is always set and contains the parent element as value.

The return value of such a method has to be a string containing the element el formatted correctly as LaTeX markup.

Public Class Methods

new(root, options) click to toggle source

Initialize the LaTeX converter with the root element and the conversion options.

# File lib/kramdown/converter/latex.rb, line 45
def initialize(root, options)
  super
  #TODO: set the footnote counter at the beginning of the document
  @options[:footnote_nr]
  @data[:packages] = Set.new
end

Public Instance Methods

attribute_list(el) click to toggle source

Return a LaTeX comment containing all attributes as 'key="value"' pairs.

# File lib/kramdown/converter/latex.rb, line 583
def attribute_list(el)
  attrs = el.attr.map {|k,v| v.nil? ? '' : " #{k}=\"#{v.to_s}\""}.compact.sort.join('')
  attrs = "   % #{attrs}" if !attrs.empty?
  attrs
end
convert(el, opts = {}) click to toggle source

Dispatch the conversion of the element el to a convert_TYPE method using the type of the element.

# File lib/kramdown/converter/latex.rb, line 54
def convert(el, opts = {})
  send("convert_#{el.type}", el, opts)
end
convert_a(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 218
def convert_a(el, opts)
  url = el.attr['href']
  if url =~ /^#/
    "\\hyperlink{#{url[1..-1]}}{#{inner(el, opts)}}"
  else
    "\\href{#{url}}{#{inner(el, opts)}}"
  end
end
convert_abbreviation(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 559
def convert_abbreviation(el, opts)
  el.value
end
convert_blank(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 74
def convert_blank(el, opts)
  opts[:result] =~ /\n\n\Z|\A\Z/ ? "" : "\n"
end
convert_blockquote(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 114
def convert_blockquote(el, opts)
  latex_environment(el.children.size > 1 ? 'quotation' : 'quote', el, inner(el, opts))
end
convert_br(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 212
def convert_br(el, opts)
  res = "\\newline"
  res << "\n" if (c = opts[:parent].children[opts[:index]+1]) && (c.type != :text || c.value !~ /^\s*\n/)
  res
end
convert_codeblock(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 97
def convert_codeblock(el, opts)
  show_whitespace = el.attr['class'].to_s =~ /\bshow-whitespaces\b/
  lang = extract_code_language(el.attr)
  if show_whitespace || lang
    options = []
    options << "showspaces=%s,showtabs=%s" % (show_whitespace ? ['true', 'true'] : ['false', 'false'])
    options << "language=#{lang}" if lang
    options << "basicstyle=\\ttfamily\\footnotesize,columns=fixed,frame=tlbr"
    id = el.attr['id']
    options << "label=#{id}" if id
    attrs = attribute_list(el)
    "#{latex_link_target(el)}\\begin{lstlisting}[#{options.join(',')}]\n#{el.value}\n\\end{lstlisting}#{attrs}\n"
  else
    "#{latex_link_target(el)}\\begin{verbatim}#{el.value}\\end{verbatim}\n"
  end
end
convert_codespan(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 240
def convert_codespan(el, opts)
  "{\\tt #{latex_link_target(el)}#{escape(el.value)}}"
end
convert_comment(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 208
def convert_comment(el, opts)
  el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") + "\n"
end
convert_dd(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 155
def convert_dd(el, opts)
  "#{latex_link_target(el)}#{inner(el, opts)}\n\n"
end
convert_dl(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 143
def convert_dl(el, opts)
  latex_environment('description', el, inner(el, opts))
end
convert_dt(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 151
def convert_dt(el, opts)
  "\\item[#{inner(el, opts)}] "
end
convert_em(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 257
def convert_em(el, opts)
  "\\emph{#{latex_link_target(el)}#{inner(el, opts)}}"
end
convert_entity(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 527
def convert_entity(el, opts)
  entity_to_latex(el.value)
end
convert_footnote(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 244
def convert_footnote(el, opts)
  @data[:packages] << 'fancyvrb'
  "\\footnote{#{inner(el.value, opts).rstrip}}"
end
convert_header(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 118
def convert_header(el, opts)
  type = @options[:latex_headers][output_header_level(el.options[:level]) - 1]
  if ((id = el.attr['id']) ||
      (@options[:auto_ids] && (id = generate_id(el.options[:raw_text])))) && in_toc?(el)
    "\\#{type}{#{inner(el, opts)}}\\hypertarget{#{id}}{}\\label{#{id}}\n\n"
  else
    "\\#{type}*{#{inner(el, opts)}}\n\n"
  end
end
convert_hr(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 128
def convert_hr(el, opts)
  attrs = attribute_list(el)
  "#{latex_link_target(el)}\\begin{center}#{attrs}\n\\rule{3in}{0.4pt}\n\\end{center}#{attrs}\n"
end
convert_html_element(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 159
def convert_html_element(el, opts)
  if el.value == 'i'
    "\\emph{#{inner(el, opts)}}"
  elsif el.value == 'b'
    "\\emph{#{inner(el, opts)}}"
  else
    warning("Can't convert HTML element")
    ''
  end
end
convert_img(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 227
def convert_img(el, opts)
  if el.attr['src'] =~ /^(https?|ftps?):\/\//
    warning("Cannot include non-local image")
    ''
  elsif !el.attr['src'].empty?
    @data[:packages] << 'graphicx'
    "#{latex_link_target(el)}\\includegraphics{#{el.attr['src']}}"
  else
    warning("Cannot include image with empty path")
    ''
  end
end
convert_li(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 147
def convert_li(el, opts)
  "\\item #{latex_link_target(el, true)}#{inner(el, opts).sub(/\n+\Z/, '')}\n"
end
convert_math(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 546
def convert_math(el, opts)
  @data[:packages] += ]amssymb amsmath amsthm amsfonts]
  if el.options[:category] == :block
    if el.value =~ /\A\s*\\begin\{/
      el.value
    else
      latex_environment('displaymath', el, el.value)
    end
  else
    "$#{el.value}$"
  end
end
convert_ol(el, opts) click to toggle source
Alias for: convert_ul
convert_p(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 82
def convert_p(el, opts)
  if el.children.size == 1 && el.children.first.type == :img && !(img = convert_img(el.children.first, opts)).empty?
    convert_standalone_image(el, opts, img)
  else
    "#{latex_link_target(el)}#{inner(el, opts)}\n\n"
  end
end
convert_raw(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 249
def convert_raw(el, opts)
  if !el.options[:type] || el.options[:type].empty? || el.options[:type].include?('latex')
    el.value + (el.options[:category] == :block ? "\n" : '')
  else
    ''
  end
end
convert_root(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 70
def convert_root(el, opts)
  inner(el, opts)
end
convert_smart_quote(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 540
def convert_smart_quote(el, opts)
  res = entity_to_latex(smart_quote_entity(el)).chomp('{}')
  res << "{}" if ((nel = opts[:parent].children[opts[:index]+1]) && nel.type == :smart_quote) || res =~ /\w$/
  res
end
convert_standalone_image(el, opts, img) click to toggle source

Helper method used by convert_p to convert a paragraph that only contains a single :img element.

# File lib/kramdown/converter/latex.rb, line 92
def convert_standalone_image(el, opts, img)
  attrs = attribute_list(el)
  "\\begin{figure}#{attrs}\n\\begin{center}\n#{img}\n\\end{center}\n\\caption{#{escape(el.children.first.attr['alt'])}}\n#{latex_link_target(el, true)}\n\\end{figure}#{attrs}\n"
end
convert_strong(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 261
def convert_strong(el, opts)
  "\\textbf{#{latex_link_target(el)}#{inner(el, opts)}}"
end
convert_table(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 181
def convert_table(el, opts)
  @data[:packages] << 'longtable'
  align = el.options[:alignment].map {|a| TABLE_ALIGNMENT_CHAR[a]}.join('|')
  attrs = attribute_list(el)
  "#{latex_link_target(el)}\\begin{longtable}{|#{align}|}#{attrs}\n\\hline\n#{inner(el, opts)}\\hline\n\\end{longtable}#{attrs}\n\n"
end
convert_tbody(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 192
def convert_tbody(el, opts)
  inner(el, opts)
end
convert_td(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 204
def convert_td(el, opts)
  inner(el, opts)
end
convert_text(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 78
def convert_text(el, opts)
  escape(el.value)
end
convert_tfoot(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 196
def convert_tfoot(el, opts)
  "\\hline \\hline \n#{inner(el, opts)}"
end
convert_thead(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 188
def convert_thead(el, opts)
  "#{inner(el, opts)}\\hline\n"
end
convert_tr(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 200
def convert_tr(el, opts)
  el.children.map {|c| send("convert_#{c.type}", c, opts)}.join(' & ') + "\\\\\n"
end
convert_typographic_sym(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 536
def convert_typographic_sym(el, opts)
  TYPOGRAPHIC_SYMS[el.value]
end
convert_ul(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 133
def convert_ul(el, opts)
  if !@data[:has_toc] && (el.options[:ial][:refs].include?('toc') rescue nil)
    @data[:has_toc] = true
    '\tableofcontents'
  else
    latex_environment(el.type == :ul ? 'itemize' : 'enumerate', el, inner(el, opts))
  end
end
Also aliased as: convert_ol
convert_xml_comment(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 170
def convert_xml_comment(el, opts)
  el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") + "\n"
end
convert_xml_pi(el, opts) click to toggle source
# File lib/kramdown/converter/latex.rb, line 174
def convert_xml_pi(el, opts)
  warning("Can't convert XML PI")
  ''
end
entity_to_latex(entity) click to toggle source
# File lib/kramdown/converter/latex.rb, line 516
def entity_to_latex(entity)
  text, package = ENTITY_CONV_TABLE[entity.code_point]
  if text
    @data[:packages] << package if package
    text
  else
    warning("Couldn't find entity with code #{entity.code_point} in substitution table!")
    ''
  end
end
escape(str) click to toggle source

Escape the special LaTeX characters in the string str.

# File lib/kramdown/converter/latex.rb, line 600
def escape(str)
  str.gsub(ESCAPE_RE) {|m| ESCAPE_MAP[m]}
end
inner(el, opts) click to toggle source

Return the converted content of the children of el as a string.

# File lib/kramdown/converter/latex.rb, line 59
def inner(el, opts)
  result = ''
  options = opts.dup.merge(:parent => el)
  el.children.each_with_index do |inner_el, index|
    options[:index] = index
    options[:result] = result
    result << send("convert_#{inner_el.type}", inner_el, options)
  end
  result
end
latex_environment(type, el, text) click to toggle source

Wrap the text inside a LaTeX environment of type type. The element el is passed on to the method attribute_list -- the resulting string is appended to both the \begin and the \end lines of the LaTeX environment for easier post-processing of LaTeX environments.

# File lib/kramdown/converter/latex.rb, line 566
def latex_environment(type, el, text)
  attrs = attribute_list(el)
  "\\begin{#{type}}#{latex_link_target(el)}#{attrs}\n#{text.rstrip}\n\\end{#{type}}#{attrs}\n"
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.