class Rabbit::Parser::Markdown::Converter

Public Class Methods

new(canvas) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 36
def initialize(canvas)
  @canvas = canvas
  @slides = []
  @slide = nil
  @slide_property_mode = false
end

Public Instance Methods

convert(element, context=nil) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 43
def convert(element, context=nil)
  method_name = "convert_#{element.type}"
  method_name << "_#{context}" if context
  __send__(method_name, element)
end

Private Instance Methods

apply_class(children, klass) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 181
def apply_class(children, klass)
  return children if klass.nil?
  classes = klass.split
  classes.inject(children) do |nested_children, klass|
    CustomTag.new(klass, nested_children)
  end
end
convert_a(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 386
def convert_a(element)
  ref = ReferText.new(convert_container(element))
  ref.to = element.attr["href"]
  ref
end
convert_blank(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 128
def convert_blank(element)
  :no_element
end
convert_blockquote(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 341
def convert_blockquote(element)
  BlockQuote.new(convert_container(element))
end
convert_br(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 392
def convert_br(element)
  Text.new("\n")
end
convert_codeblock(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 301
def convert_codeblock(element)
  content = element.value.chomp
  language = detect_codeblock_language(element)
  if language
    converted = convert_codeblock_language(element, language, content)
  end
  converted || PreformattedBlock.new(PreformattedText.new(text(content)))
end
convert_codeblock_language(element, language, content) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 325
def convert_codeblock_language(element, language, content)
  case language
  when "blockdiag"
    args = [@canvas, content]
    Ext::Image.make_image_from_file(*args) do |src_file_path|
      [
        Ext::BlockDiag.make_image(src_file_path, element.attr, @canvas),
        element.attr,
      ]
    end
  else
    logger = @canvas.logger
    Ext::Rouge.highlight(language, content, logger)
  end
end
convert_codespan(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 396
def convert_codespan(element)
  Code.new(text(element.value))
end
convert_comment(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 297
def convert_comment(element)
  :no_element
end
convert_container(element, context=nil) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 50
def convert_container(element, context=nil)
  elements = []
  element.children.each do |child|
    element = convert(child, context)
    case element
    when nil, :no_element
      # ignore
    else
      elements << element
    end
  end
  elements
end
convert_dd(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 159
def convert_dd(element)
  DescriptionContent.new(convert_container(element))
end
convert_dl(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 132
def convert_dl(element)
  list = DescriptionList.new
  term = nil
  content = nil
  convert_container(element).each do |item|
    case item
    when DescriptionTerm
      list << DescriptionListItem.new(term, content) if term
      term = item
    when DescriptionContent
      content = item
    end
  end
  list << DescriptionListItem.new(term, content) if term
  list
end
convert_dt(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 155
def convert_dt(element)
  DescriptionTerm.new(create_paragraph(convert_container(element)))
end
convert_em(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 371
def convert_em(element)
  Emphasis.new(Emphasis.new(convert_container(element)))
end
convert_header(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 96
def convert_header(element)
  slide, @slide = @slide, nil
  contents = convert_container(element)
  case element.options[:level]
  when 1
    if @slides.empty?
      @slide = TitleSlide.new(Title.new(contents))
    else
      @slide = Element::Slide.new(HeadLine.new(contents))
      @slide << Body.new
    end
    @slides << @slide
    @slide
  when 2
    if /\Anote\z/i =~ contents.first.text
      NoteSetter.new(@slides.last)
    else
      SlidePropertySetter.new(@slides.last)
    end
  else
    nil
  end
end
convert_hr(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 293
def convert_hr(element)
  raise ParseError, _("horizontal rule isn't supported.")
end
convert_html_element(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 425
def convert_html_element(element)
  raise ParseError, _("HTML isn't supported.")
end
convert_img(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 345
def convert_img(element)
  options = element.attr.dup
  uri = options.delete("src")
  title = options.delete("title")
  alt = options.delete("alt")
  caption = title || alt
  options["caption"] ||= caption if caption
  if options["align"] == "right"
    body = @slides.last.body
    if body["background-image"]
      raise ParseError,
            _("multiple ![]('XXX.png'){:align='right'} " + \
              "isn't supported.")
    end
    body["background-image"] = uri
    options.each do |name, value|
      name = name.to_s.gsub(/_/, "-")
      body["background-image-#{name}"] = value
    end
    :no_element
  else
    image = Ext::Image.make_image(@canvas, uri, options)
    image || text(alt || src)
  end
end
convert_li_ol(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 240
def convert_li_ol(element)
  create_list_item(EnumListItem, convert_container(element))
end
convert_li_ul(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 228
def convert_li_ul(element)
  create_list_item(ItemListItem, convert_container(element))
end
convert_math(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 379
def convert_math(element)
  args = [@canvas, element.value]
  Ext::Image.make_image_from_file(*args) do |src_file_path|
    [Ext::TeX.make_image_by_LaTeX(src_file_path, {}, @canvas), {}]
  end
end
convert_note(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 404
def convert_note(element)
  # TODO: Should we validate element.options[:category] == "span"?
  Ext::Inline.note(convert_container(element))
end
convert_ol(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 232
def convert_ol(element)
  i = 1
  create_list(EnumList, convert_container(element, "ol")) do |list, item|
    item.order = i
    i += 1
  end
end
convert_p(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 163
def convert_p(element)
  child_types = element.children.collect {|child| child.type}
  if child_types == [:img]
    convert_container(element)[0]
  else
    if child_types.include?(:img)
      raise ParseError,
              _("multiple ![alt]{image} in a paragraph isn't supported.")
    end
    if element.options[:transparent] and child_types == [:text]
      element.children.first.value.chomp!
    end
    converted_children = apply_class(convert_container(element),
                                     element.attr["class"])
    create_paragraph(converted_children)
  end
end
convert_root(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 64
def convert_root(element)
  target = nil
  mode = :ignore
  convert_container(element).each do |content|
    case content
    when :no_element
      next
    when nil
      mode = :ignore
    when Element::Slide
      target = content.body
      @canvas << content
      mode = :display
    when TitleSlide
      target = content
      @canvas << content
      mode = :display
    when SlidePropertySetter, NoteSetter
      target = content
      mode = :property
    else
      case mode
      when :display
        target << content
      when :property
        target.apply(content)
      end
    end
  end
  burn_out_pause_targets
end
convert_smart_quote(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 244
def convert_smart_quote(element)
  Text.new(Parser::Ext::Entity::TABLE[element.value.to_s])
end
convert_strikethrough(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 421
def convert_strikethrough(element)
  DeletedText.new(text(element.value))
end
convert_strong(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 375
def convert_strong(element)
  Emphasis.new(Emphasis.new(convert_container(element)))
end
convert_table(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 252
def convert_table(element)
  table = Table.new
  convert_container(element).each do |item|
    table << item
  end
  table
end
convert_tag(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 409
def convert_tag(element)
  name = element.attr["name"]
  if name.nil?
    raise ParseError, _("tag name is missing.")
  end
  if element.children.empty?
    CustomTag.new(name)
  else
    CustomTag.new(name, convert_container(element))
  end
end
convert_tbody(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 273
def convert_tbody(element)
  TableBody.new(convert_container(element))
end
convert_td(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 281
def convert_td(element)
  if @in_table_header
    header = TableHeader.new(convert_container(element))
    def header.default_align
      Pango::Alignment::CENTER
    end
    header
  else
    TableCell.new(convert_container(element))
  end
end
convert_text(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 124
def convert_text(element)
  text(element.value)
end
convert_thead(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 260
def convert_thead(element)
  in_table_header do
    TableHead.new(convert_container(element))
  end
end
convert_tr(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 277
def convert_tr(element)
  TableRow.new(convert_container(element))
end
convert_typographic_sym(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 248
def convert_typographic_sym(element)
  Text.new(Parser::Ext::Entity::TABLE[element.value.to_s])
end
convert_ul(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 224
def convert_ul(element)
  create_list(ItemList, convert_container(element, "ul"))
end
convert_wait(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 400
def convert_wait(element)
  WaitTag.new
end
create_list(list_class, contents) { |list, content| ... } click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 189
def create_list(list_class, contents)
  list = list_class.new
  contents.each do |content|
    list << content
    if block_given?
      yield(list, content)
    end
  end
  list
end
create_list_item(list_item_class, contents) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 200
def create_list_item(list_item_class, contents)
  list_item = list_item_class.new(contents)

  waited_paragraphs = list_item.elements.find_all do |element|
    element.is_a?(Paragraph) and element.have_wait_tag?
  end
  if waited_paragraphs.empty?
    list_item.default_visible = true
    list_item.clear_theme
  else
    waited_paragraphs.each do |paragraph|
      paragraph.default_visible = true
      paragraph.clear_theme
      unregister_pause(paragraph)
    end

    list_item.default_visible = false
    list_item.clear_theme
    register_pause(list_item)
  end

  list_item
end
create_paragraph(elements) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 149
def create_paragraph(elements)
  paragraph = Paragraph.new(elements)
  register_pause(paragraph) if paragraph.have_wait_tag?
  paragraph
end
detect_codeblock_language(element) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 310
def detect_codeblock_language(element)
  lang = element.attr["lang"]
  return lang if lang

  language = element.attr["language"]
  return language if language

  klass = element.attr["class"]
  if klass and /\Alanguage-/ =~ klass
    return $POSTMATCH
  end

  nil
end
in_table_header() { || ... } click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 266
def in_table_header
  in_table_header, @in_table_header = @in_table_header, true
  yield
ensure
  @in_table_header = in_table_header
end
text(content) click to toggle source
# File lib/rabbit/parser/markdown/converter.rb, line 120
def text(content)
  Text.new(Parser::Ext::Escape.escape_meta_character(content))
end