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:
The element of type NAME to be converted.
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.
Initialize the LaTeX converter with the root element and the conversion options.
# File lib/kramdown/converter/latex.rb, line 32 def initialize(root, options) super #TODO: set the footnote counter at the beginning of the document @options[:footnote_nr] @data[:packages] = Set.new end
Return a LaTeX comment containing all attributes as 'key="value"' pairs.
# File lib/kramdown/converter/latex.rb, line 576 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
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 41 def convert(el, opts = {}) send("convert_#{el.type}", el, opts) end
# File lib/kramdown/converter/latex.rb, line 205 def convert_a(el, opts) url = el.attr['href'] if url.start_with?('#') "\\hyperlink{#{escape(url[1..-1])}}{#{inner(el, opts)}}" else "\\href{#{escape(url)}}{#{inner(el, opts)}}" end end
# File lib/kramdown/converter/latex.rb, line 546 def convert_abbreviation(el, opts) @data[:packages] += ]acronym] "\\ac{#{normalize_abbreviation_key(el.value)}}" end
# File lib/kramdown/converter/latex.rb, line 61 def convert_blank(el, opts) opts[:result] =~ /\n\n\Z|\A\Z/ ? "" : "\n" end
# File lib/kramdown/converter/latex.rb, line 101 def convert_blockquote(el, opts) latex_environment(el.children.size > 1 ? 'quotation' : 'quote', el, inner(el, opts)) end
# File lib/kramdown/converter/latex.rb, line 199 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
# File lib/kramdown/converter/latex.rb, line 84 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
# File lib/kramdown/converter/latex.rb, line 227 def convert_codespan(el, opts) "{\\tt #{latex_link_target(el)}#{escape(el.value)}}" end
# File lib/kramdown/converter/latex.rb, line 195 def convert_comment(el, opts) el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") << "\n" end
# File lib/kramdown/converter/latex.rb, line 142 def convert_dd(el, opts) "#{latex_link_target(el)}#{inner(el, opts)}\n\n" end
# File lib/kramdown/converter/latex.rb, line 130 def convert_dl(el, opts) latex_environment('description', el, inner(el, opts)) end
# File lib/kramdown/converter/latex.rb, line 138 def convert_dt(el, opts) "\\item[#{inner(el, opts)}] " end
# File lib/kramdown/converter/latex.rb, line 244 def convert_em(el, opts) "\\emph{#{latex_link_target(el)}#{inner(el, opts)}}" end
# File lib/kramdown/converter/latex.rb, line 514 def convert_entity(el, opts) entity_to_latex(el.value) end
# File lib/kramdown/converter/latex.rb, line 231 def convert_footnote(el, opts) @data[:packages] << 'fancyvrb' "\\footnote{#{inner(el.value, opts).rstrip}}" end
# File lib/kramdown/converter/latex.rb, line 105 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
# File lib/kramdown/converter/latex.rb, line 115 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
# File lib/kramdown/converter/latex.rb, line 146 def convert_html_element(el, opts) if el.value == 'i' || el.value == 'em' "\\emph{#{inner(el, opts)}}" elsif el.value == 'b' || el.value == 'strong' "\\textbf{#{inner(el, opts)}}" else warning("Can't convert HTML element") '' end end
# File lib/kramdown/converter/latex.rb, line 214 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
# File lib/kramdown/converter/latex.rb, line 134 def convert_li(el, opts) "\\item #{latex_link_target(el, true)}#{inner(el, opts).sub(/\n+\Z/, '')}\n" end
# File lib/kramdown/converter/latex.rb, line 533 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
# File lib/kramdown/converter/latex.rb, line 69 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
# File lib/kramdown/converter/latex.rb, line 236 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
# File lib/kramdown/converter/latex.rb, line 57 def convert_root(el, opts) inner(el, opts) end
# File lib/kramdown/converter/latex.rb, line 527 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
Helper method used by convert_p to convert a paragraph that only contains a single :img element.
# File lib/kramdown/converter/latex.rb, line 79 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
# File lib/kramdown/converter/latex.rb, line 248 def convert_strong(el, opts) "\\textbf{#{latex_link_target(el)}#{inner(el, opts)}}" end
# File lib/kramdown/converter/latex.rb, line 168 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
# File lib/kramdown/converter/latex.rb, line 179 def convert_tbody(el, opts) inner(el, opts) end
# File lib/kramdown/converter/latex.rb, line 191 def convert_td(el, opts) inner(el, opts) end
# File lib/kramdown/converter/latex.rb, line 65 def convert_text(el, opts) escape(el.value) end
# File lib/kramdown/converter/latex.rb, line 183 def convert_tfoot(el, opts) "\\hline \\hline \n#{inner(el, opts)}" end
# File lib/kramdown/converter/latex.rb, line 175 def convert_thead(el, opts) "#{inner(el, opts)}\\hline\n" end
# File lib/kramdown/converter/latex.rb, line 187 def convert_tr(el, opts) el.children.map {|c| send("convert_#{c.type}", c, opts)}.join(' & ') << "\\\\\n" end
# File lib/kramdown/converter/latex.rb, line 523 def convert_typographic_sym(el, opts) TYPOGRAPHIC_SYMS[el.value] end
# File lib/kramdown/converter/latex.rb, line 120 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
# File lib/kramdown/converter/latex.rb, line 157 def convert_xml_comment(el, opts) el.value.split(/\n/).map {|l| "% #{l}"}.join("\n") + "\n" end
# File lib/kramdown/converter/latex.rb, line 161 def convert_xml_pi(el, opts) warning("Can't convert XML PI") '' end
# File lib/kramdown/converter/latex.rb, line 503 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 the special LaTeX characters in the string str.
# File lib/kramdown/converter/latex.rb, line 593 def escape(str) str.gsub(ESCAPE_RE) {|m| ESCAPE_MAP[m]} end
Return the converted content of the children of el as a string.
# File lib/kramdown/converter/latex.rb, line 46 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
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 559 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
Return a string containing a valid hypertarget command if the element has an ID defined, or nil otherwise. If the parameter add_label is true, a label command will also be used additionally to the hypertarget command.
# File lib/kramdown/converter/latex.rb, line 567 def latex_link_target(el, add_label = false) if (id = el.attr['id']) "\\hypertarget{#{id}}{}" << (add_label ? "\\label{#{id}}" : '') else nil end end
Generated with the Darkfish Rdoc Generator 2.