1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
|
module WikiCloth
class WikiBuffer::Table < WikiBuffer
def initialize(data="",options={})
super(data,options)
self.buffer_type = "table"
@start_table = true
@start_row = false
@start_caption = false
@in_quotes = false
end
def table_caption
@caption ||= ""
return @caption.kind_of?(Hash) ? @caption[:value] : @caption
end
def table_caption_attributes
@caption.kind_of?(Hash) ? @caption[:style] : ""
end
def rows
@rows ||= [ [] ]
end
def to_html
row_count = 0
ret = "<table" + (params[0].blank? ? "" : " #{params[0].strip}") + ">"
ret += "<caption" + (self.table_caption_attributes.blank? ? "" : " #{table_caption_attributes.strip}") +
">#{table_caption.strip}</caption>" unless self.table_caption.blank?
for row in rows
row_count += 1
unless row.empty?
ret += "<tr" + (params[row_count].nil? || params[row_count].blank? ? "" : " #{params[row_count].strip}") + ">"
for cell in row
cell_attributes = cell[:style].blank? ? "" : parse_attributes(cell[:style].strip).collect { |k,v| "#{k}=\"#{v}\"" }.join(" ")
cell_attributes = cell_attributes.blank? ? "" : " #{cell_attributes}"
ret += "<#{cell[:type]}#{cell_attributes}>\n#{cell[:value].strip}\n</#{cell[:type]}>"
end
ret += "</tr>"
end
end
ret += "</table>"
end
protected
def parse_attributes(data)
attribute_name = nil
in_quotes = false
quote_type = nil
ret = {}
d = ""
prev_char = nil
for char in data.each_char
case
when char == "=" && attribute_name.nil? && in_quotes == false
attribute_name = d.strip
d = ""
when (char == '"' || char == "'") && in_quotes == false && !attribute_name.nil?
in_quotes = true
quote_type = char
when (char == quote_type && in_quotes == true && prev_char != '\\') || (char == ' ' && in_quotes == false && !d.blank?)
ret[attribute_name] = d if WikiBuffer::HTMLElement::ALLOWED_ATTRIBUTES.include?(attribute_name)
attribute_name = nil
in_quotes = false
d = ""
else
prev_char = char
d += char
end
end
ret
end
def rows=(val)
@rows = val
end
def table_caption_attributes=(val)
@caption = { :style => val, :value => self.table_caption } unless @caption.kind_of?(Hash)
@caption[:style] = val if @caption.kind_of?(Hash)
end
def table_caption=(val)
@caption = val unless @caption.kind_of?(Hash)
@caption[:value] = val if @caption.kind_of?(Hash)
end
def next_row()
self.params << ""
self.rows << []
end
def next_cell(type="td")
if self.rows[-1].size == 0
self.rows[-1] = [ { :type => type, :value => "", :style => "" } ]
else
self.rows[-1][-1][:value] = self.data
self.rows[-1] << { :type => type, :value => "", :style => "" }
end
end
def new_char()
if @check_cell_data == 1
case
when current_char != '|' && @start_caption == false && (self.rows[-1][-1].nil? || self.rows[-1][-1][:style].blank?)
self.next_cell() if self.rows[-1][-1].nil?
self.rows[-1][-1][:style] = self.data
self.data = ""
when current_char != '|' && @start_caption == true && self.table_caption_attributes.blank?
self.table_caption_attributes = self.data
self.data = ""
end
@check_cell_data = 0
end
case
# Next table cell in row (TD)
when current_char == "|" && (previous_char == "\n" || previous_char == "|") && @in_quotes == false
self.data.chop! if self.data[-1,1] == "|"
self.next_cell() unless self.data.blank? && previous_char == "|"
self.data = ""
# Next table cell in row (TH)
when current_char == "!" && (previous_char == "\n" || previous_char == "!") && @in_quotes == false
self.data.chop!
self.next_cell('th')
self.data = ""
# End of a table
when current_char == '}' && previous_char == '|'
self.data = ""
self.rows[-1].pop
return false
# Start table caption
when current_char == '+' && previous_char == '|' && @in_quotes == false
self.data = ""
self.rows[-1].pop
@start_caption = true
# Table cell might have attributes
when current_char == '|' && previous_char != "\n" && @in_quotes == false
@check_cell_data = 1 unless @start_table
# End table caption
when current_char == "\n" && @start_caption == true && @in_quotes == false
@start_caption = false
self.table_caption = self.data
self.data = ""
# in quotes
when current_char == '"' && previous_char != '\\'
@in_quotes = !@in_quotes
self.data += '"'
# Table params
when current_char == "\n" && @start_table == true && @in_quotes == false
@start_table = false
unless self.data.blank?
self.current_param = self.data
self.params << ""
end
self.data = ""
# Table row params
when current_char == "\n" && @start_row == true && @in_quotes == false
@start_row = false
unless self.data.blank?
self.current_param = self.data
end
self.data = ""
# Start new table row
when current_char == '-' && previous_char == '|' && @in_quotes == false
self.data.chop!
self.rows[-1].pop
self.next_row()
@start_row = true
else
self.data << current_char
end
return true
end
end
end
|