class WikiCloth::WikiBuffer

Constants

BOLD_ITALIC_MAP

Public Class Methods

new(data="",options={}) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 4
def initialize(data="",options={})
  @options = options
  @options[:buffer] ||= self
  self.data = data
  self.buffer_type = nil
  @section_count = 0
  @buffers ||= [ ]
  @buffers << self
  @list_data = []
  @check_new_tag = false
  @indent = nil
  @previous_line_empty = false
  @paragraph_open = false
end

Public Instance Methods

add_char(c) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 151
def add_char(c)
  self.previous_char = self.current_char
  self.current_char = c

  if self.check_globals() == false
    case
    when @buffers.size == 1
      return self.new_char()
    when @buffers[-1].add_char(c) == false && self.class == WikiBuffer
      tmp = @buffers.pop
      @buffers[-1].data += tmp.send("to_#{@options[:output]}")
      # any data left in the buffer we feed into the parent
      unless tmp.data.nil?
        tmp.data.each_char { |x| self.add_char(x) }
      end
    end
  end
end
add_word(w) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 128
def add_word(w)
  self.previous_char = w[-2,1]
  self.current_char = w[-1,1]
  @buffers[-1].data += w
end
buffer_type() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 62
def buffer_type
  @buffer_type
end
buffers() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 27
def buffers
  @buffers
end
check_globals() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 70
def check_globals()
  return false if self.class != WikiBuffer

  if previous_char == "\n" || previous_char == ""
    if @indent == @buffers[-1].object_id && current_char != " "
      @indent = nil
      # close pre tag
      cc_temp = current_char
      "</pre>\n".each_char { |c| self.add_char(c) }
      # get the parser back on the right track
      "\n#{cc_temp}".each_char { |c| @buffers[-1].add_char(c) }
      return true
    end
    if current_char == " " && @indent.nil? && ![WikiBuffer::HTMLElement,WikiBuffer::Var].include?(@buffers[-1].class)
      "\n<pre> ".each_char { |c| @buffers[-1].add_char(c) }
      @indent = @buffers[-1].object_id
      return true
    end
  end

  if @buffers[-1].run_globals?
    # new html tag
    if @check_new_tag == true && current_char =~ /([a-z])/ && !@buffers[-1].skip_html?
      @buffers[-1].data.chop!
      parent = @buffers[-1].element_name if @buffers[-1].class == WikiBuffer::HTMLElement
      @buffers << WikiBuffer::HTMLElement.new("",@options,parent)
    end
    @check_new_tag = current_char == '<' ? true : false

    # global
    case
    # start variable
    when previous_char == '{' && current_char == '{'
      if @buffers[-1].instance_of?(WikiBuffer::Var) && @buffers[-1].tag_start == true
        @buffers[-1].tag_size += 1
      else
        @buffers[-1].data.chop! if @buffers[-1].data[-1,1] == '{'
        @buffers << WikiBuffer::Var.new("",@options)
      end
      return true

    # start link
    when current_char == '[' && previous_char != '[' && !@buffers[-1].skip_links?
      @buffers << WikiBuffer::Link.new("",@options)
      return true

    # start table
    when previous_char == '{' && current_char == "|"
      @buffers[-1].data.chop!
      @buffers << WikiBuffer::Table.new("",@options)
      return true

    end
  end

  return false
end
data() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 39
def data
  @data ||= ""
end
debug() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 19
def debug
  self.params[0].blank? ? self.class.to_s : self.params[0]
end
eof() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 134
def eof()
  return if @buffers.size == 1

  if self.class == WikiBuffer
    while @buffers.size > 1
      @buffers[-1].eof()
      tmp = @buffers.pop
      @buffers[-1].data += tmp.send("to_#{@options[:output]}")
      unless tmp.data.blank?
        tmp.data.each_char { |x| self.add_char(x) }
      end
    end
  else
    # default cleanup tasks
  end
end
get_param(name,default=nil) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 47
def get_param(name,default=nil)
  ret = nil
  self.params.each do |param|
    ret = param[:value] if param.instance_of?(Hash) && param[:name] == name
  end
  ret.nil? ? default : ret
end
in_template?() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 55
def in_template?
  @options[:buffer].buffers.each do |b|
    return true if b.instance_of?(WikiBuffer::HTMLElement) && b.element_name == "template"
  end
  false
end
params() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 43
def params
  @params ||= [ "" ]
end
run_globals?() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 23
def run_globals?
  true
end
skip_html?() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 31
def skip_html?
  false
end
to_html() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 66
def to_html
  self.params.join("\n") + (@list_data.empty? ? "" : render_list_data()) + (@paragraph_open ? "</p>" : "")
end

Protected Instance Methods

behavior_switch_key_name(name) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 243
def behavior_switch_key_name(name)
  keys = [:toc,:notoc,:forcetoc,:noeditsection,:editsection]
  locales = [@options[:locale],I18n.default_locale]
  values = {}

  locales.each do |locale|
    I18n.with_locale(locale) do
      keys.each do |key|
        values[I18n.t("behavior_switches.#{key.to_s}")] = "behavior_switches.#{key.to_s}"
      end
    end
  end

  values[name]
end
buffer_type=(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 291
def buffer_type=(val)
  @buffer_type = val
end
current_char() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 303
def current_char
  @current_char ||= ""
end
current_char=(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 299
def current_char=(val)
  @current_char = val
end
current_line() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 319
def current_line
  @current_line ||= ""
end
current_line=(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 315
def current_line=(val)
  @current_line = val
end
current_param=(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 279
def current_param=(val)
  unless self.params[-1].nil? || self.params[-1].kind_of?(String)
    self.params[-1][:value] = val
  else
    self.params[-1] = val
  end
end
data=(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 295
def data=(val)
  @data = val
end
gen_heading(hnum,title) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 259
def gen_heading(hnum,title)
  id = get_id_for(title.gsub(/\s+/,'_'))
  "<h#{hnum}>" + (@options[:noedit] == true ? "" :
    "<span class=\"editsection\">&#91;<a href=\"" + @options[:link_handler].section_link(id) +
    "\" title=\"#{I18n.t('edit section', :name => title)}\">#{I18n.t('edit')}</a>&#93;</span> ") +
    "<span class=\"mw-headline\" id=\"#{id}\"><a name=\"#{id}\">#{title}</a></span></h#{hnum}>\n"
end
get_id_for(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 267
def get_id_for(val)
  val.gsub!(/[^A-Za-z0-9_]+/,'')
  @idmap ||= {}
  @idmap[val] ||= 0
  @idmap[val] += 1
  @idmap[val] == 1 ? val : "#{val}-#{@idmap[val]}"
end
list_inner_tag_for(tag) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 446
def list_inner_tag_for(tag)
  case tag
  when "#" then "li"
  when "*" then "li"
  when ";" then "dt"
  when ":" then "dd"
  end
end
list_tag_for(tag) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 437
def list_tag_for(tag)
  case tag
  when "#" then "ol"
  when "*" then "ul"
  when ";" then "dl"
  when ":" then "dl"
  end
end
name_current_param() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 275
def name_current_param()
  params[-1] = { :value => "", :name => params[-1] } unless params[-1].kind_of?(Hash) || params[-1].nil?
end
new_char() click to toggle source

only executed in the default state

# File lib/wikicloth/wiki_buffer.rb, line 172
def new_char()
  case
  when current_char == "\n"
    # Underline, and Strikethrough
    if @options[:extended_markup] == true
      self.data.gsub!(/---([^-]+)---/,"<strike>\\1</strike>")
      self.data.gsub!(/_([^_]+)_/,"<u>\\1</u>")
    end

    # Behavior Switches
    self.data.gsub!(/__([\w]+)__/) { |r|
      case behavior_switch_key_name($1)
      when "behavior_switches.toc"
        @options[:link_handler].toc(@options[:sections], @options[:toc_numbered])
      when "behavior_switches.noeditsection"
        @options[:noedit] = true
      when "behavior_switches.editsection"
        @options[:noedit] = false
      else
        ""
      end
    }

    # Horizontal Rule
    self.data.gsub!(/^([-]{4,})/) { |r| "<hr />" }

    render_bold_italic()

    # Lists
    tmp = ''
    self.data.each_line do |line|
      if line =~ /^([#\*:;]+)/
        # Add current line to list data
        @list_data << line
      else
        # render list if list data was just closed
        tmp += render_list_data() unless @list_data.empty?
        tmp += line
      end
    end
    self.data = tmp

    # Headings
    is_heading = false
    self.data.gsub!(/^([=]{1,6})\s*(.*?)\s*(\1)/) { |r|
      is_heading = true
      (@paragraph_open ? "</p>" : "") + gen_heading($1.length,$2)
    }

    # Paragraphs
    if is_heading
      @paragraph_open = false
    else
      if self.data =~ /^\s*$/ && @paragraph_open && @list_data.empty?
        self.data = "</p>#{self.data}"
        @paragraph_open = false
      else
        if self.data !~ /^\s*$/
          self.data = "<p>#{self.data}" and @paragraph_open = true unless @paragraph_open
        end
      end
    end

    self.params << self.data.auto_link
    self.data = ""
  else
    self.data << current_char
  end
  return true
end
params=(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 287
def params=(val)
  @params = val
end
previous_char() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 311
def previous_char
  @previous_char
end
previous_char=(val) click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 307
def previous_char=(val)
  @previous_char = val
end
render_bold_italic() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 361
def render_bold_italic()

  commands = []
  self.data.scan(/([\']{2,5})/) do
      commands << {
        :len => $1.length,
        :type => [nil, nil, :italic, :bold, :four, :bold_italic][$1.length],
        :pos => $~.offset(0).first
      }
    end
  commands << {:type => :finish}

  state = 0
  commands.each do |c|
      trans = BOLD_ITALIC_MAP[state][c[:type]]
      c[:output] = trans.last
      state = trans.first
    end

  index = 0
  self.data.gsub!(/([\']{2,5})/) do
      output = commands[index][:output]
      index += 1
      output
    end
  self.data << commands.last[:output]
end
render_list_data() click to toggle source
# File lib/wikicloth/wiki_buffer.rb, line 389
def render_list_data()

  ret = ""
  last = ""

  process_line = Proc.new do |pieces, content|

      common = 0
      (0..last.length - 1).each do |i|
        if last[i] == pieces[i]
          common += 1
        else
          break
        end
      end

      close = last[common..-1].reverse
      open = pieces[common..-1]

      close.each_char do |e|
        ret << "</#{list_inner_tag_for(e)}></#{list_tag_for(e)}>"
      end
      if open == '' && pieces != ''
        if last != ''
          ret << "</#{list_inner_tag_for(pieces[-1,1])}>"
        end
        ret << "<#{list_inner_tag_for(pieces[-1,1])}>"
      end
      open.each_char do |e|
        ret << "<#{list_tag_for(e)}><#{list_inner_tag_for(e)}>"
      end
      
      ret << content

      last = pieces.clone
    end

  (@list_data + ['']).each do |l|
    if l =~ /^([#\*:;]+)\s*(.*)$/
      process_line.call($1, $2)
    end
  end
  process_line.call('', '')

  @list_data = []
  ret + "\n"
end