require 'slaw/grammars/terminals' require 'slaw/grammars/tables_nodes'

module Slaw

module Grammars
  grammar Tables
    ##########
    # wikimedia-style tables
    #
    # this grammar doesn't support inline table cells (eg: | col1 || col2 || col3)
    # instead, the builder preprocesses tables to break inline cells onto their own
    # lines, which we do support.

    rule table
      table_start
      table_body
      table_end
      <Table>
    end

    rule table_start
      space? '{|' eol
    end

    rule table_end
      space? '|}' eol
    end

    rule table_body
      (table_row / table_cell)*
    end

    rule table_row
      space? '|-' space? eol
    end

    rule table_cell
      # don't match end-of-table
      !table_end

      # td (|) or th (!) cell marker with attributes
      table_cell_start attribs:table_attribs? space?

      # cell's first content line, then multiple lines
      content:(line:table_line (!table_cell_start space? line:table_line)*)
      <TableCell>
    end

    # td (|) or th (!) cell marker
    rule table_cell_start
      space? [!|]

      {
        def th?
          elements[1].text_value == '!'
        end
      }
    end

    rule table_line
      inline_items:inline_items? eol
      <TableLine>
    end

    # foo=one bar=two |
    rule table_attribs
      space? attribs:(table_attrib+) '|'
    end

    # foo=bar
    # foo="bar"
    # foo='bar'
    rule table_attrib
      name:([a-z_-]+) '=' value:(
                                 ('"' (!'"' .)* '"') /
                                 ("'" (!"'" .)* "'"))
      space?
    end

    include Terminals
  end
end

end