module IRuby module LaTeX extend self def vector(v) x = 'c' * v.size y = v.map(&:to_s).join(' & ') "$$\\left(\\begin{array}{#{x}} #{y} \\end{array}\\right)$$" end def matrix(m, row_count, column_count) s = "$$\\left(\\begin{array}{#{'c' * column_count}}\n" (0...row_count).each do |i| s << ' ' << m[i,0].to_s (1...column_count).each do |j| s << '&' << m[i,j].to_s end s << "\\\\\n" end s << "\\end{array}\\right)$$" end end module HTML extend self def table(obj, maxrows: 15, maxcols: 15, **options) raise ArgumentError, 'Invalid :maxrows' if maxrows && maxrows < 3 raise ArgumentError, 'Invalid :maxcols' if maxcols && maxcols < 3 return obj unless obj.respond_to?(:each) rows = [] if obj.respond_to?(:keys) # Hash of Arrays header = obj.keys keys = (0...obj.keys.size).to_a cols = obj.values.map {|x| [x].flatten(1) } num_rows = cols.map(&:size).max rows = [] (0...num_rows).each do |i| rows << [] (0...cols.size).each do |j| rows[i][j] = cols[j][i] end end else keys = nil array_size = 0 obj.each do |row| if row.respond_to?(:keys) # Array of Hashes keys ||= Set.new keys.merge(row.keys) elsif row.respond_to?(:map) # Array of Arrays array_size = row.size if array_size < row.size end rows << row end if keys header = keys.to_a keys.merge(0...array_size) else keys = 0...array_size end keys = keys.to_a end header ||= keys if options[:header] rows1, rows2 = rows, nil keys1, keys2 = keys, nil header1, header2 = header, nil if maxcols && keys.size > maxcols keys1 = keys[0...maxcols / 2] keys2 = keys[-maxcols / 2...-1] if header header1 = header[0...maxcols / 2] header2 = header[-maxcols / 2...-1] end end if maxrows && rows.size > maxrows rows1 = rows[0...maxrows / 2] rows2 = rows[-maxrows / 2...-1] end table = '
#{cell k} | " }.join table << "… | " << header2.map {|k| "#{cell k} | " }.join if keys2 table << '
---|---|---|
1 ? " colspan='#{keys1.size}'" : ''}>⋮ | " table << "⋱ | 1 ? " colspan='#{keys2.size}'" : ''}>⋮ | " if keys2 table << '