Coder Social home page Coder Social logo

Comments (8)

jeffreytse avatar jeffreytse commented on August 30, 2024 9

As we known, kramdown only supports simple tables with no block elements inside cells, no colspan/rowspan or anything else. We have to use an HTML table for more complex tables.

To support col-span and row-span even more table features that using an awesome non-html solution, I think the below Jekyll plugin could help you:

jekyll-spaceship - 🚀 A Jekyll plugin to provide powerful supports for table, mathjax, mermaid, plantuml, emoji, youtube, etc.

https://github.com/jeffreytse/jekyll-spaceship

For now, these extended features are provided:

  • Cells spanning multiple columns
  • Cells spanning multiple rows
  • Cells text align separately
  • Table header not required
  • Grouped table header rows or data rows
    ...

from kramdown.

unibr avatar unibr commented on August 30, 2024 4

@Tuckie to support col-span and row-span, revise converter/html.rb (it should work. it is revised from workable code for kramdown-1.1.0, but itself not tested.):

# col span previous cell if cell is empty
# if want to keep an empty one, use non-white char like '-'
# 
# following table contains two layer headers
# first header has two colspan with first empty
# second header has two cells and one colspan cell
# |   |   | Column 1 | |
# | a | b | haha     | |
# |----
# 
# row span cells with same text
# following table contains rowspan
# | :---: | -----
# | names | tom |
# | names | jerry |
# | film  | cartoon |
# 
# use option `table_rowspan` and `table_colspan` to control
# option values: :all, :first, nil
def convert_table(el, indent)
  attr = el.attr.dup
  format_as_indented_block_html(el.type, attr, inner(el, indent), indent)
end

def convert_tbody(el, indent)
  span = @options[:table_rowspan]
  if span == :all
    col_rowspan_all el
  elsif span == :first
    col_rowspan_first el
  end

  span = @options[:table_colspan]
  el.children.each{|row| row_colspan(row)} if span == :all

  format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
end

def convert_thead(el, indent)
  span = @options[:table_colspan]
  if span == :all
    el.children.each{|row| row_colspan(row)}
  elsif span == :first
    row = el.children.first
    row_colspan row
  end

  format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
end

alias :convert_tfoot :convert_thead


def convert_tr(el, indent)
  format_as_indented_block_html(el.type, el.attr, inner(el, indent), indent)
end

def convert_td(el, indent)
  return '' if el.attr[:skip]
  res = inner(el, indent)
  type = el.type
  type = :th if type == :td and @stack[-2].type == :thead
  attr = el.attr
  alignment = @stack[-3].options[:alignment][@stack.last.children.index(el)]
  # do not apply align style to th
  if alignment != :default && type != :th
    attr = el.attr.dup
    attr['style'] = (attr.has_key?('style') ? "#{attr['style']}; ": '') << "text-align: #{alignment}"
  end
  format_as_block_html(type, attr, res.empty? ? entity_to_str(ENTITY_NBSP) : res, indent)
end

alias :convert_th  :convert_td


def mark_skip_cell(cell)
  cell.attr[:skip] = true
end

def mark_span_cell(cell, span, size)
  cell.attr[span] = size if size > 1
end

def row_colspan(row)
  span = :colspan
  cells = row.children
  groups = cells.chunk{|c| c.children.empty?}.to_a
  total = groups.size
  start = 0
  if groups.first[0]
    start = 1
    count = groups.first[1].size
    cell = groups.first[1][0]
    mark_span_cell cell, span, count
    (1...count).each{|i| mark_skip_cell groups.first[1][i]}
  end
  (start...total).each do |i|
    if groups[i][0]
      groups[i][1].each{|cell| mark_skip_cell cell}
    end
    next if i == total - 1
    next unless groups[i+1][0]
    cell = groups[i][1][-1]
    cell.attr[span] = groups[i+1][1].size + 1
  end
end

# perform col_rowspan on one row
def col_rowspan_row(cells)
  span = :rowspan
  cells.chunk{|c| c.inspect}.each do |r,cs|
    first = cs.first
    total = cs.size
    unless total < 2
      mark_span_cell first, span, total
      cs[1..-1].each{|c| mark_skip_cell c}
    end
  end
end

# only for first col
def col_rowspan_first(body)
  rows = body.children
  cells = rows.map{|r| r.children.first}
  col_rowspan_row cells
end

# rowspan for all cols
def col_rowspan_all(body)
  rows = body.children
  cells = rows.map(&:children)
  cols = cells.transpose
  cols.each do |cells|
    col_rowspan_row cells
  end
end

from kramdown.

nickwelhar avatar nickwelhar commented on August 30, 2024 2

A detailed tutorial about HTML Tables...HTML Table help

nick

from kramdown.

 avatar commented on August 30, 2024

#41 applies here

From John Gruber himself

Markdown is not a replacement for HTML, or even close to it. Its syntax is
very small, corresponding only to a very small subset of HTML tags. The idea
is not to create a syntax that makes it easier to insert HTML tags. In my
opinion, HTML tags are already easy to insert. The idea for Markdown is to
make it easy to read, write, and edit prose.

from kramdown.

gettalong avatar gettalong commented on August 30, 2024

kramdown only supports simple tables with no block elements inside cells, no colspan/rowspan or anything else. Use an HTML table for more complex tables.

from kramdown.

unibr avatar unibr commented on August 30, 2024

I have made some modification to support col-span and row-span, which utilizes some cell text. I have no idea whether it is a good convention for kramdown, but it works for me, at least to some extent. I will share it later, and hope it helps.

from kramdown.

Tuckie avatar Tuckie commented on August 30, 2024

Interesting, thank you!

from kramdown.

dolfandringa avatar dolfandringa commented on August 30, 2024

A detailed tutorial about HTML Tables...HTML Table help

nick

Sorry, but he didn't ask about HTML tables. He even said that he was looking for a non-html solution.

from kramdown.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.