def tag(type, body, args = {}) if args[:style].is_a? Hash args[:style] = args[:style].map { |k, v| "#{k}: #{v};" }.join(" ") end "<#{type} #{args.map { |k, v| "#{k}='#{v}'" }.join(" ")}>#{body}" end def data_table(schema, data, params = {}) tablename_style = params.fetch(:tablename_style, { "font-weight" => "bold", "text-decoration" => "underline" }) rownum_style = params.fetch(:rownum_style, { "font-size" => "50%", "font-face" => "Courier, fixed-width", "vertical-align"=> "middle" }) annotation_style = params.fetch(:annotation_style, rownum_style) separator_style = params.fetch(:separator_style, { "border-right" => "1px solid black" }) num_cols = data.map { |row| row.size if row.is_a? Array }.compact.max data = data.map do |row| case row when Array row.map do |cell| tag("td", cell) end when String [ tag("td", row, colspan: num_cols) ] else raise "Unknown rowtype: #{row}" end end if params.has_key? :annotations data = data.zip(params[:annotations]).map do |row, annot| if annot.nil? then row else row+[tag("td", "→ "+annot.to_s, annotation_style)] end end num_cols += 1 end data = [schema.map { |cell| tag("th", cell) }] + data if params.fetch(:rowids, false) data = data.map.with_index do |row, idx| if idx == 0 then [tag("th", "#", style: separator_style)]+row else [tag("td", idx+params.fetch(:rowid_offset, 0), style: rownum_style.merge(separator_style))]+row end end elsif params.has_key? :name data = data.map { |row| [tag("td", "", style: separator_style)]+row } end if params.has_key? :name data[0][0] = tag("th", params[:name], style: tablename_style.merge(separator_style)) end row_args = [{}] * data.size case params.fetch(:build_in, :none) when :none then when :by_row then row_args = [{}] + [{ "class" => "fragment" }]*(data.size-1) when Array then row_args = [{}] + params[:build_in].map do |order| if order <= 0 then {} else { "class" => "fragment", "data-fragment-index" => order } end end end return tag("table", data.zip(row_args).map { |row, args| tag("tr", row.join, args) }.join("\n"), params.fetch(:table_args, {}) ) end