lib/infoboxer/parser/table.rb in infoboxer-0.3.3 vs lib/infoboxer/parser/table.rb in infoboxer-0.4.0

- old
+ new

@@ -1,5 +1,7 @@ +# frozen_string_literal: true + module Infoboxer class Parser # http://en.wikipedia.org/wiki/Help:Table module Table include Tree @@ -10,11 +12,11 @@ log 'Starting to parse table' prms = table_params log "Table params found #{prms}" - table = Tree::Table.new(Nodes[], prms) + table = Tree::Table.new(Nodes[], **prms) @context.next! guarded_loop do table_next_line(table) or break @@ -49,70 +51,75 @@ table_cells(table) when /^\s*{{/ # template can be at row level table_template(table) when nil return false + when /^(?<level>={2,})\s*(?<text>.+?)\s*\k<level>$/ # heading implicitly closes the table + @context.prev! + return false else return table_cell_cont(table) end true # should continue parsing end def table_row(table, param_str) log 'Table row found' - table.push_children(TableRow.new(Nodes[], parse_params(param_str))) + table.push_children(TableRow.new(Nodes[], **parse_params(param_str))) end def table_caption(table) log 'Table caption found' @context.skip(/^\s*\|\+\s*/) - params = if @context.check(/[^|{|\[]+\|([^\|]|$)/) + params = if @context.check(/[^|{\[]+\|([^|]|$)/) parse_params(@context.scan_until(/\|/)) else {} end children = inline(/^\s*([|!]|{\|)/) if @context.matched @context.unscan_matched! @context.prev! # compensate next! which will be done in table() end - table.push_children(TableCaption.new(children.strip, params)) + table.push_children(TableCaption.new(children.strip, **params)) end def table_cells(table, cell_class = TableCell) log 'Table cells found' table.push_children(TableRow.new) unless table.children.last.is_a?(TableRow) row = table.children.last @context.skip(/\s*[!|]\s*/) guarded_loop do - params = if @context.check(/[^|{|\[]+\|([^\|]|$)/) + params = if @context.check(/[^|{\[]+\|([^|]|$)/) parse_params(@context.scan_until(/\|/)) else {} end content = short_inline(/(\|\||!!)/) - row.push_children(cell_class.new(content, params)) + row.push_children(cell_class.new(content, **params)) break if @context.eol? end end def table_template(table) contents = paragraph(/^\s*([|!]|{\|)/).to_templates? - if (row = table.children.last).is_a?(TableRow) - if (cell = row.children.last).is_a?(BaseCell) - cell.push_children(*contents) - else - row.push_children(*contents) - end - else - table.push_children(*contents) - end + # Note: in fact, without full template parsing, we CAN'T know what level to insert it: + # Template can be something like <tr><td>Foo</td></tr> + # But for consistency, we insert all templates inside the <td>, forcing this <td> + # to exist. + + table.push_children(TableRow.new) unless table.children.last.is_a?(TableRow) + row = table.children.last + row.push_children(TableCell.new) unless row.children.last.is_a?(BaseCell) + cell = row.children.last + + cell.push_children(*contents) end # Good news, everyone! Table can be IMPLICITLY closed when it's # not "cell" context. # @@ -128,9 +135,10 @@ end unless container # return "table not continued" unless row is empty return true if @context.current.empty? + @context.prev! return false end container.push_children(paragraph(/^\s*([|!]|{\|)/))