.bundle/ruby/2.0.0/gems/kramdown-1.4.1/lib/kramdown/parser/kramdown/table.rb
# Parse the table at the current location.
Parse the table at the current location.
Parse the table at the current location .
def parse_table
        return false if !after_block_boundary?
        orig_pos = @src.pos
        table = new_block_el(:table, nil, nil, :alignment => [], :location => @src.current_line_number)
        leading_pipe = (@src.check(TABLE_LINE) =~ /^\s*\|/)
        @src.scan(TABLE_SEP_LINE)
        rows = []
        has_footer = false
        columns = 0
        add_container = lambda do |type, force|
          if !has_footer || type != :tbody || force
            cont = Element.new(type)
            cont.children, rows = rows, []
            table.children << cont
          end
        end
        while !@src.eos?
          break if !@src.check(TABLE_LINE)
          if @src.scan(TABLE_SEP_LINE) && !rows.empty?
            if table.options[:alignment].empty? && !has_footer
              add_container.call(:thead, false)
              table.options[:alignment] = @src[1].scan(TABLE_HSEP_ALIGN).map do |left, right|
                (left.empty? && right.empty? && :default) || (right.empty? && :left) || (left.empty? && :right) || :center
              end
            else 
              add_container.call(:tbody, false)
            end
          elsif @src.scan(TABLE_FSEP_LINE)
            add_container.call(:tbody, true) if !rows.empty?
            has_footer = true
          elsif @src.scan(TABLE_ROW_LINE)
            trow = Element.new(:tr)
            env = save_env
            cells = []
            @src[1].split(/(<code.*?>.*?<\/code>)/).each_with_index do |str, i|
              if i % 2 == 1
                (cells.empty? ? cells : cells.last) << str
              else
                reset_env(:src => Kramdown::Utils::StringScanner.new(str, @src.current_line_number))
                root = Element.new(:root)
                parse_spans(root, nil, [:codespan])
                root.children.each do |c|
                  if c.type == :raw_text
                    f, *l = c.value.split(/\\\|/, -1).map {|t| t.split(/\|/, -1)}.inject([]) do |memo, t|
                      memo.last << "|#{t.shift}" if memo.size > 0
                      memo.concat(t)
                    end
                    (cells.empty? ? cells : cells.last) << f
                    cells.concat(l)
                  else
                    delim = (c.value.scan(/`+/).max || '') + '`'
                    tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}"
                    (cells.empty? ? cells : cells.last) << tmp
                  end
                end
              end
            end
            restore_env(env)
            cells.shift if leading_pipe && cells.first.strip.empty?
            cells.pop if cells.last.strip.empty?
            cells.each do |cell_text|
              tcell = Element.new(:td)
              tcell.children << Element.new(:raw_text, cell_text.strip)
              trow.children << tcell
            end
            columns = [columns, cells.length].max
            rows << trow
          else
            break
          end
        end
        if !before_block_boundary?
          @src.pos = orig_pos
          return false
        end
        env = save_env
        l_src = ::Kramdown::Utils::StringScanner.new(extract_string(orig_pos...(@src.pos-1), @src),
                                                     @src.current_line_number)
        reset_env(:src => l_src)
        root = Element.new(:root)
        parse_spans(root, nil, [:codespan, :span_html])
        restore_env(env)
        pipe_on_line = false
        while (c = root.children.shift)
          lines = c.value.split(/\n/)
          if c.type == :codespan
            if lines.size > 2 || (lines.size == 2 && !pipe_on_line)
              break
            elsif lines.size == 2 && pipe_on_line
              pipe_on_line = false
            end
          else
            break if lines.size > 1 && !pipe_on_line && lines.first !~ /^#{TABLE_PIPE_CHECK}/
            pipe_on_line = (lines.size > 1 ? false : pipe_on_line) || (lines.last =~ /^#{TABLE_PIPE_CHECK}/)
          end
        end
        @src.pos = orig_pos and return false if !pipe_on_line
        add_container.call(has_footer ? :tfoot : :tbody, false) if !rows.empty?
        if !table.children.any? {|el| el.type == :tbody}
          warning("Found table without body on line #{table.options[:location]} - ignoring it")
          @src.pos = orig_pos
          return false
        end
        table.children.each do |kind|
          kind.children.each do |row|
            (columns - row.children.length).times do
              row.children << Element.new(:td)
            end
          end
        end
        if table.options[:alignment].length > columns
          table.options[:alignment] = table.options[:alignment][0...columns]
        else
          table.options[:alignment] += [:default] * (columns - table.options[:alignment].length)
        end
        @tree.children << table
        true
      end
def parse_table return false if ! after_block_boundary? orig_pos = @src . pos table = new_block_el ( :table , nil , nil , :alignment => [ ] , :location => @src . current_line_number ) leading_pipe = ( @src . check ( TABLE_LINE ) =~ / ^ \s * \| / ) @src . scan ( TABLE_SEP_LINE ) rows = [ ] has_footer = false columns = 0 add_container = lambda do | type , force | if ! has_footer || type != :tbody || force cont = Element . new ( type ) cont . children , rows = rows , [ ] table . children << cont end end while ! @src . eos? break if ! @src . check ( TABLE_LINE ) if @src . scan ( TABLE_SEP_LINE ) && ! rows . empty? if table . options [ :alignment ] . empty? && ! has_footer add_container . call ( :thead , false ) table . options [ :alignment ] = @src [ 1 ] . scan ( TABLE_HSEP_ALIGN ) . map do | left , right | ( left . empty? && right . empty? && :default ) || ( right . empty? && :left ) || ( left . empty? && :right ) || :center end else add_container . call ( :tbody , false ) end elsif @src . scan ( TABLE_FSEP_LINE ) add_container . call ( :tbody , true ) if ! rows . empty? has_footer = true elsif @src . scan ( TABLE_ROW_LINE ) trow = Element . new ( :tr ) env = save_env cells = [ ] @src [ 1 ] . split ( / (<code.*?>.*?< \/ code>) / ) . each_with_index do | str , i | if i % 2 == 1 ( cells . empty? ? cells : cells . last ) << str else reset_env ( :src => Kramdown :: Utils :: StringScanner . new ( str , @src . current_line_number ) ) root = Element . new ( :root ) parse_spans ( root , nil , [ :codespan ] ) root . children . each do | c | if c . type == :raw_text f , * l = c . value . split ( / \\ \| / , - 1 ) . map { | t | t . split ( / \| / , - 1 ) } . inject ( [ ] ) do | memo , t | memo . last << "|#{t.shift}" if memo . size > 0 memo . concat ( t ) end ( cells . empty? ? cells : cells . last ) << f cells . concat ( l ) else delim = ( c . value . scan ( / `+ / ) . max || '' ) + '`' tmp = "#{delim}#{' ' if delim.size > 1}#{c.value}#{' ' if delim.size > 1}#{delim}" ( cells . empty? ? cells : cells . last ) << tmp end end end end restore_env ( env ) cells . shift if leading_pipe && cells . first . strip . empty? cells . pop if cells . last . strip . empty? cells . each do | cell_text | tcell = Element . new ( :td ) tcell . children << Element . new ( :raw_text , cell_text . strip ) trow . children << tcell end columns = [ columns , cells . length ] . max rows << trow else break end end if ! before_block_boundary? @src . pos = orig_pos return false end env = save_env l_src = :: Kramdown :: Utils :: StringScanner . new ( extract_string ( orig_pos ... ( @src . pos - 1 ) , @src ) , @src . current_line_number ) reset_env ( :src => l_src ) root = Element . new ( :root ) parse_spans ( root , nil , [ :codespan , :span_html ] ) restore_env ( env ) pipe_on_line = false while ( c = root . children . shift ) lines = c . value . split ( / \n / ) if c . type == :codespan if lines . size > 2 || ( lines . size == 2 && ! pipe_on_line ) break elsif lines . size == 2 && pipe_on_line pipe_on_line = false end else break if lines . size > 1 && ! pipe_on_line && lines . first !~ / ^ #{ TABLE_PIPE_CHECK } / pipe_on_line = ( lines . size > 1 ? false : pipe_on_line ) || ( lines . last =~ / ^ #{ TABLE_PIPE_CHECK } / ) end end @src . pos = orig_pos and return false if ! pipe_on_line add_container . call ( has_footer ? :tfoot : :tbody , false ) if ! rows . empty? if ! table . children . any? { | el | el . type == :tbody } warning ( "Found table without body on line #{table.options[:location]} - ignoring it" ) @src . pos = orig_pos return false end table . children . each do | kind | kind . children . each do | row | ( columns - row . children . length ) . times do row . children << Element . new ( :td ) end end end if table . options [ :alignment ] . length > columns table . options [ :alignment ] = table . options [ :alignment ] [ 0 ... columns ] else table . options [ :alignment ] += [ :default ] * ( columns - table . options [ :alignment ] . length ) end @tree . children << table true end
Parse the table at the current location.
Parse the table at the current location .
# treat as normal separator line # parse possible code spans on the line and correctly split the line into cells # Only on Ruby 1.9: f, *l = c.value.split(/(?<!\\)\|/).map {|t| t.gsub(/\\\|/, '|')} # Parse all lines of the table with the code span parser # Check if each line has at least one unescaped pipe that is not inside a code span/code # HTML element # Note: It doesn't matter that we parse *all* span HTML elements because the row splitting # algorithm above only takes <code> elements into account! # adjust all table rows to have equal number of columns, same for alignment defs