module MaRuKu::Out::Latex

Constants

LATEX_ADD_SLASH

These are TeX's special characters

LATEX_TO_CHARCODE

These, we transform to {tt char<ascii code>}

Latex_preamble_enc_cjk
Latex_preamble_enc_utf8
OtherGoodies

other things that are good on the eyes

SAFE_CHARS

Public Instance Methods

array_to_latex(array, join_char='') click to toggle source
# File lib/maruku/output/to_latex.rb, line 531
def array_to_latex(array, join_char='')
  e = []
  array.each do |c|
    if c.kind_of?(String)
      e << string_to_latex(c)
    else method = c.kind_of?(Maruku::MDElement) ? "to_latex_#{c.node_type}" : "to_latex"
      next unless c.respond_to?(method)

      h =  c.send(method)

      unless h
        raise "Nil latex for #{c.inspect} created with method #{method}"
      end

      if h.kind_of? Array
        e.concat h
      else
        e << h
      end
    end
  end
  e.join(join_char)
end
children_to_latex() click to toggle source

Convert each child to html

# File lib/maruku/output/to_latex.rb, line 527
def children_to_latex
  array_to_latex(@children)
end
latex_color(s, command='color') click to toggle source

color{name} color[rgb]{1,0.2,0.3}

# File lib/maruku/output/to_latex.rb, line 161
def latex_color(s, command='color')
  if s =~ /\A\#([1-9A-F]{1,2})([1-9A-F]{1,2})([1-9A-F]{1,2})\z/i
    # convert from 0-255 or 0-15 to 0.0-1.0
    r, g, b = [$1, $2, $3].map {|c| c.hex / (c.length == 1 ? 15.0 : 255.0) }
    "\\#{command}[rgb]{%0.2f,%0.2f,%0.2f}" % [r, g, b]
  else
    "\\#{command}{#{s}}"
  end
end
latex_escape(source) click to toggle source

the ultimate escaping (is much better than using verb)

# File lib/maruku/output/to_latex.rb, line 318
def latex_escape(source)
  source.chars.inject('') do |s, b|
    s << if b == '\'
           '~'
         elsif SAFE_CHARS.include? b
           b
         else
           "\\char%d" % b[0].ord
         end
  end
end
render_latex_signature() click to toggle source
# File lib/maruku/output/to_latex.rb, line 126
  def render_latex_signature
    "\\vfill
\\hrule
\\vspace{1.2mm}
\\begin{tiny}
Created by \\href{#{MaRuKu::MARUKU_URL}}{Maruku} #{self.nice_date}.
\\end{tiny}"
  end
string_to_latex(s) click to toggle source

escapes special characters

# File lib/maruku/output/to_latex.rb, line 562
def string_to_latex(s)
  s = escape_to_latex(s)
  OtherGoodies.each do |k, v|
    s.gsub!(k, v)
  end
  s
end
to_latex() click to toggle source

Render as a LaTeX fragment

# File lib/maruku/output/to_latex.rb, line 28
def to_latex
  children_to_latex
end
to_latex_abbr() click to toggle source
# File lib/maruku/output/to_latex.rb, line 483
def to_latex_abbr
  children_to_latex
end
to_latex_cell() click to toggle source
# File lib/maruku/output/to_latex.rb, line 438
def to_latex_cell
  s=""
  if @attributes.has_key?(:colspan)
    # TODO figure out how to set the alignment (defaulting to left for now)
    s="\\multicolumn {"<< @attributes[:colspan]<<"}{|l|}{"<<children_to_latex<<"}"
  else
    children_to_latex
  end
end
to_latex_code() click to toggle source

begin maruku_doc

Attribute: latex_use_listings
Scope: document
Output: latex
Summary: Support for `listings` package.
Related: code_show_spaces, code_background_color, lang, code_lang

If the `latex_use_listings` attribute is specified, then
code block are rendered using the `listings` package.
Otherwise, a standard `verbatim` environment is used.

* If the `lang` attribute for the code block has been specified,
  it gets passed to the `listings` package using the `lstset` macro.
  The default lang for code blocks is specified through
  the `code_lang` attribute.

    \lstset{language=ruby}

  Please refer to the documentation of the `listings` package for
  supported languages.

  If a language is not supported, the `listings` package will emit
  a warning during the compilation. Just press enter and nothing
  wrong will happen.

* If the `code_show_spaces` is specified, than spaces and tabs will
  be shown using the macro:

    \lstset{showspaces=true,showtabs=true}

* The background color is given by `code_background_color`.

end

# File lib/maruku/output/to_latex.rb, line 230
def to_latex_code
  if get_setting(:latex_use_listings)
    @doc.latex_require_package('listings')

    s = "\\lstset{columns=fixed,frame=shadowbox}"

    if get_setting(:code_show_spaces)
      s << "\\lstset{showspaces=true,showtabs=true}\n"
    else
      s << "\\lstset{showspaces=false,showtabs=false}\n"
    end

    color = latex_color get_setting(:code_background_color)

    s << "\\lstset{backgroundcolor=#{color}}\n"

    s << "\\lstset{basicstyle=\\ttfamily\\footnotesize}\n"


    lang = self.attributes[:lang] || @doc.attributes[:code_lang] || '{}'
    s << "\\lstset{language=#{lang}}\n" if lang

    "#{s}\n\\begin{lstlisting}\n#{self.raw_code}\n\\end{lstlisting}"
  else
    "\\begin{verbatim}#{self.raw_code}\\end{verbatim}\n"
  end
end
to_latex_definition() click to toggle source
# File lib/maruku/output/to_latex.rb, line 469
def to_latex_definition
  s = ""

  self.terms.each do |t|
    s << "\n\\item[#{t.children_to_latex}] "
  end

  self.definitions.each do |d|
    s << "#{d.children_to_latex} \n"
  end

  s
end
to_latex_definition_list() click to toggle source

Definition lists ###

# File lib/maruku/output/to_latex.rb, line 463
def to_latex_definition_list
  s = "\\begin{description}\n"
  s << children_to_latex
  s << "\\end{description}\n"
end
to_latex_div() click to toggle source
# File lib/maruku/output/to_latex.rb, line 501
def to_latex_div
  type = self.attributes[:class]
  id = self.attributes[:id]
  case type
  when /^un_(\w*)/
    @children.shift
    s = "\\begin{u#{$1}}\n"
    s << children_to_latex
    s << "\\end{u#{$1}}\n"
  when /^num_(\w*)/
    @children.delete_at(0)
    s = "\\begin{#{$1}}"
    s << "\n\\label{#{id}}\\hypertarget{#{id}}{}\n"
    s << children_to_latex
    s << "\\end{#{$1}}\n"
  when /^proof/
    @children.delete_at(0)
    s = "\\begin{proof}\n"
    s << children_to_latex
    s << "\\end{proof}\n"
  else
    children_to_latex
  end
end
to_latex_divref() click to toggle source
# File lib/maruku/ext/math/to_latex.rb, line 20
def to_latex_divref
  "\\ref{#{self.refid}}"
end
to_latex_document() click to toggle source

Render as a complete LaTeX document

# File lib/maruku/output/to_latex.rb, line 44
  def to_latex_document
    body = to_latex

    if get_setting(:maruku_signature)
      body << render_latex_signature
    end

    required = self.latex_required_packages.map do |p|
      "\\usepackage{#{p}}\n"
    end.join

    #=begin maruku_doc
    # Attribute: latex_cjk
    # Scope:     document
    # Output:    latex
    # Summary:   Support for CJK characters.
    #
    # If the `latex_cjk` attribute is specified, then appropriate headers
    # are added to the LaTeX preamble to support Japanese fonts.
    # You have to have these fonts installed -- and this can be a pain.
    #
    # If `latex_cjk` is specified, this is added to the preamble:
    #
    # <?mrk puts "ciao" ?>
    #
    # <?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_cjk) ?>
    #
    #
    # while the default is to add this:
    #
    # <?mrk md_codeblock(Maruku::MDDocument::Latex_preamble_enc_utf8) ?>
    #
    #=end

    encoding = get_setting(:latex_cjk) ? Latex_preamble_enc_cjk : Latex_preamble_enc_utf8

    #=begin maruku_doc
    # Attribute: latex_preamble
    # Scope:     document
    # Output:    latex
    # Summary:   User-defined preamble.
    #
    # If the `latex_preamble` attribute is specified, then its value
    # will be used as a custom preamble.
    #
    # For example:
    #
    #   Title: My document
    #   Latex preamble: preamble.tex
    #
    # will produce:
    #
    #   ...
    #   \input{preamble.tex}
    #   ...
    #
    #=end

    user_preamble = (file = @doc.attributes[:latex_preamble]) ? "\\input{#{file}}\n" : ""

    "\\documentclass{article}

% Packages required to support encoding
#{encoding}

% Packages required by code
#{required}

% Packages always used
\\usepackage{hyperref}
\\usepackage{xspace}
\\usepackage[usenames,dvipsnames]{color}
\\hypersetup{colorlinks=true,urlcolor=blue}

#{user_preamble}

\\begin{document}
#{body}
\\end{document}
"
  end
to_latex_email_address() click to toggle source
# File lib/maruku/output/to_latex.rb, line 405
def to_latex_email_address
  "\\href{mailto:#{self.email}}{#{latex_escape(self.email)}}"
end
to_latex_emphasis() click to toggle source
# File lib/maruku/output/to_latex.rb, line 300
def to_latex_emphasis
  "\\emph{#{children_to_latex}}"
end
to_latex_entity() click to toggle source
# File lib/maruku/output/to_latex.rb, line 330
def to_latex_entity
  entity_name = self.entity_name

  entity = MaRuKu::Out::EntityTable.instance.entity(entity_name)
  unless entity
    maruku_error "I don't know how to translate entity '#{entity_name}' to LaTeX."
    return ""
  end

  replace = entity.latex_string
  @doc.latex_require_package entity.latex_package if entity.latex_package

  if replace
    if replace.start_with?("\\") && !replace.end_with?('$', '}')
      replace + "{}"
    else
      replace
    end
  else
    tell_user "Cannot translate entity #{entity_name.inspect} to LaTeX."
    entity_name
  end
end
to_latex_eqref() click to toggle source
# File lib/maruku/ext/math/to_latex.rb, line 16
def to_latex_eqref
  "\\eqref{#{self.eqid}}"
end
to_latex_equation() click to toggle source
# File lib/maruku/ext/math/to_latex.rb, line 8
def to_latex_equation
  if self.label
    fix_latex("\\begin{equation}\n#{self.math.strip}\n\\label{#{self.label}}\\end{equation}\n")
  else
    fix_latex("\\begin{displaymath}\n#{self.math.strip}\n\\end{displaymath}\n")
  end
end
to_latex_footnote_reference() click to toggle source
# File lib/maruku/output/to_latex.rb, line 448
def to_latex_footnote_reference
  id = self.footnote_id
  if f = @doc.footnotes[id]
    "\\footnote{#{f.children_to_latex.strip}} "
  else
    $stderr.puts "Could not find footnote '#{id}'"
  end
end
to_latex_head_cell() click to toggle source
# File lib/maruku/output/to_latex.rb, line 434
def to_latex_head_cell
  to_latex_cell
end
to_latex_header() click to toggle source
# File lib/maruku/output/to_latex.rb, line 258
def to_latex_header
  header_levels = %w(section subsection subsubsection)
  h = header_levels[self.level - 1] || 'paragraph'

  title = children_to_latex
  if number = section_number
    title = number + title
  end

  if id = self.attributes[:id]
    # drop '#' at the beginning
    id = id[1..-1] if id.start_with? '#'
    %Q{\\hypertarget{%s}{}\\%s*{{%s}}\\label{%s}\n\n} % [ id, h, title, id ]
  else
    %Q{\\%s*{%s}\n\n} % [ h, title]
  end
end
to_latex_hrule() click to toggle source
# File lib/maruku/output/to_latex.rb, line 135
def to_latex_hrule
  "\n\\vspace{.5em} \\hrule \\vspace{.5em}\n"
end
to_latex_image() click to toggle source
# File lib/maruku/output/to_latex.rb, line 487
def to_latex_image
  id = self.ref_id
  ref = @doc.refs[sanitize_ref_id(id)] || @doc.refs[sanitize_ref_id(children_to_s)]
  if ref
    url = ref[:url]
    $stderr.puts "Images not supported yet (#{url})"
    ""
  else
    maruku_error "Could not find ref #{id.inspect} for image.\n"+
      "Available are: #{@docs.refs.keys.inspect}"
    ""
  end
end
to_latex_inline_code() click to toggle source
# File lib/maruku/output/to_latex.rb, line 354
def to_latex_inline_code
  # Convert to printable latex chars
  s = latex_escape(self.raw_code)

  color = get_setting(:code_background_color)
  colorspec = latex_color(color, 'colorbox')

  "{#{colorspec}{\\tt #{s}}}"
end
to_latex_inline_math() click to toggle source
# File lib/maruku/ext/math/to_latex.rb, line 4
def to_latex_inline_math
  fix_latex("$#{self.math.strip}$")
end
to_latex_li() click to toggle source
# File lib/maruku/output/to_latex.rb, line 292
def to_latex_li
  "\\item #{children_to_latex}\n"
end
to_latex_linebreak() click to toggle source
# File lib/maruku/output/to_latex.rb, line 139
def to_latex_linebreak
  "\\newline "
end
to_latex_ol() click to toggle source
# File lib/maruku/output/to_latex.rb, line 288
def to_latex_ol
  wrap_as_environment('enumerate')
end
to_latex_paragraph() click to toggle source
# File lib/maruku/output/to_latex.rb, line 143
def to_latex_paragraph
  children_to_latex + "\n\n"
end
to_latex_quote() click to toggle source
# File lib/maruku/output/to_latex.rb, line 284
def to_latex_quote
  wrap_as_environment('quote')
end
to_latex_raw_html() click to toggle source
# File lib/maruku/output/to_latex.rb, line 457
def to_latex_raw_html
  # Raw HTML removed in latex version
  ""
end
to_latex_strong() click to toggle source
# File lib/maruku/output/to_latex.rb, line 296
def to_latex_strong
  "\\textbf{#{children_to_latex}}"
end
to_latex_table() click to toggle source
# File lib/maruku/output/to_latex.rb, line 409
def to_latex_table
  num_columns = self.align.size

  head, *rows = @children

  h = { :center => 'c' , :left => 'l' , :right => 'r'}
  align_string = self.align.map {|a| h[a] }.join('|')

  s = "\\begin{tabular}{#{align_string}}\n"

  s << array_to_latex(head, '&') + "\\\\" + "\n"

  s << "\\hline \n"

  rows.each do |row|
    s << array_to_latex(row, '&') + "\\\\" + "\n"
  end

  s << "\\end{tabular}"

  # puts table in its own paragraph
  s << "\n\n"
end
to_latex_ul() click to toggle source
# File lib/maruku/output/to_latex.rb, line 276
def to_latex_ul
  if self.attributes[:toc]
    @doc.toc.to_latex
  else
    wrap_as_environment('itemize')
  end
end
wrap_as_environment(name) click to toggle source
# File lib/maruku/output/to_latex.rb, line 308
  def wrap_as_environment(name)
    "\\begin{#{name}}%
#{children_to_latex}
\\end{#{name}}\n"
  end
wrap_as_span(c) click to toggle source
# File lib/maruku/output/to_latex.rb, line 304
def wrap_as_span(c)
  "{#{c} #{children_to_latex}}"
end

Private Instance Methods

escape_to_latex(s) click to toggle source
# File lib/maruku/output/to_latex.rb, line 577
def escape_to_latex(s)
  s.chars.inject("") do |result, b|
    if LATEX_TO_CHARCODE.include? b
      result << "{\\tt \\symbol{#{b[0].ord}}}"
    elsif LATEX_ADD_SLASH.include? b
      result << '\' << b
    elsif b == '\'
      # there is no backslash in cmr10 fonts
      result << "$\\backslash$"
    else
      result << b
    end
  end
end
fix_latex(str) click to toggle source
# File lib/maruku/ext/math/to_latex.rb, line 26
def fix_latex(str)
  return str unless self.get_setting(:html_math_engine) == 'itex2mml'
  s = str.gsub("\\mathop{", "\\operatorname{")
  s.gsub!(/\begin\{svg\}.*?\end\{svg\}/m, " ")
  s.gsub!("\\array{","\\itexarray{")
  s.gsub("\\space{", "\\itexspace{")
end