diff --git a/Michelf/Markdown.php b/Michelf/Markdown.php index 088b7cdd..db955308 100644 --- a/Michelf/Markdown.php +++ b/Michelf/Markdown.php @@ -2512,21 +2512,25 @@ protected function doTables($text) { # $text = preg_replace_callback(' { - ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - [|] # Optional leading pipe (present) - (.+) \n # $1: Header row (at least one pipe) + ^ # Start of a line + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [|] # Optional leading pipe (present) + (.+?) # $1: Header row (at least one pipe) + (?:'.$this->id_class_attr_catch_re.')? # $2: Extra table attributes + [ ]*\n # Allowed whitespace and newline. - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - [|] ([ ]*[-:]+[-| :]*) \n # $2: Header underline + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + [|] ([ ]*[-:]+[-| :]*) # $3: Header underline + (?:'.$this->id_class_attr_catch_re.')? # $4: Extra header row attributes + [ ]*\n # Allowed whitespace and newline. - ( # $3: Cells + ( # $5: Cells (?> - [ ]* # Allowed whitespace. - [|] .* \n # Row content. + [ ]* # Allowed whitespace. + [|] .* \n # Row content. )* ) - (?=\n|\Z) # Stop at final double newline. + (?=\n|\Z) # Stop at final double newline. }xm', array(&$this, '_doTable_leadingPipe_callback'), $text); @@ -2540,19 +2544,23 @@ protected function doTables($text) { # $text = preg_replace_callback(' { - ^ # Start of a line - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - (\S.*[|].*) \n # $1: Header row (at least one pipe) + ^ # Start of a line + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + (\S.*[|].*?) # $1: Header row (at least one pipe) + (?:'.$this->id_class_attr_catch_re.')? # $2: Extra table attributes + [ ]*\n # Allowed whitespace and newline. - [ ]{0,'.$less_than_tab.'} # Allowed whitespace. - ([-:]+[ ]*[|][-| :]*) \n # $2: Header underline + [ ]{0,'.$less_than_tab.'} # Allowed whitespace. + ([-:]+[ ]*[|][-| :]*) # $3: Header underline + (?:'.$this->id_class_attr_catch_re.')? # $4: Extra header row attributes + [ ]*\n # Allowed whitespace and newline. - ( # $3: Cells + ( # $5: Cells (?> - .* [|] .* \n # Row content + .* [|] .* \n # Row content )* ) - (?=\n|\Z) # Stop at final double newline. + (?=\n|\Z) # Stop at final double newline. }xm', array(&$this, '_DoTable_callback'), $text); @@ -2560,13 +2568,15 @@ protected function doTables($text) { } protected function _doTable_leadingPipe_callback($matches) { $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; + $tableAttrs = $matches[2]; + $underline = $matches[3]; + $headAttrs = $matches[4]; + $content = $matches[5]; # Remove leading pipe for each row. $content = preg_replace('/^ *[|]/m', '', $content); - return $this->_doTable_callback(array($matches[0], $head, $underline, $content)); + return $this->_doTable_callback(array($matches[0], $head, $tableAttrs, $underline, $headAttrs, $content)); } protected function _doTable_makeAlignAttr($alignname) { @@ -2578,9 +2588,11 @@ protected function _doTable_makeAlignAttr($alignname) } protected function _doTable_callback($matches) { $head = $matches[1]; - $underline = $matches[2]; - $content = $matches[3]; - + $tableAttrs = $matches[2]; + $underline = $matches[3]; + $headAttrs = $matches[4]; + $content = $matches[5]; + # Remove any tailing pipes for each line. $head = preg_replace('/[|] *$/m', '', $head); $underline = preg_replace('/[|] *$/m', '', $underline); @@ -2606,10 +2618,16 @@ protected function _doTable_callback($matches) { $col_count = count($headers); $attr = array_pad($attr, $col_count, ''); + # Process extra table attributes + $tableAttrStr = $this->doExtraAttributes(null, $tableAttrs); + + # Process extra header row attributes + $headAttrStr = $this->doExtraAttributes(null, $headAttrs); + # Write column headers. - $text = "\n"; + $text = "\n"; $text .= "\n"; - $text .= "\n"; + $text .= "\n"; foreach ($headers as $n => $header) $text .= " ".$this->runSpanGamut(trim($header))."\n"; $text .= "\n"; @@ -2620,6 +2638,18 @@ protected function _doTable_callback($matches) { $text .= "\n"; foreach ($rows as $row) { + # Find and process any attributes at the end of each row + $rowAttrMatches = array(); + $rowAttrStr = ''; + if (preg_match('{'.$this->id_class_attr_catch_re.' *$}', $row, $rowAttrMatches)) + { + $rowAttrStr = $this->doExtraAttributes(null, $rowAttrMatches[1]); + + # If valid attributes were found, remove the attribute tag and any trailing pipe + if (strlen($rowAttrStr)) + $row = preg_replace('{[|]? *'.$this->id_class_attr_nocatch_re.' *$}', '', $row); + } + # Parsing span elements, including code spans, character escapes, # and inline HTML tags, so that pipes inside those gets ignored. $row = $this->parseSpan($row); @@ -2628,7 +2658,7 @@ protected function _doTable_callback($matches) { $row_cells = preg_split('/ *[|] */', $row, $col_count); $row_cells = array_pad($row_cells, $col_count, ''); - $text .= "\n"; + $text .= "\n"; foreach ($row_cells as $n => $cell) $text .= " ".$this->runSpanGamut(trim($cell))."\n"; $text .= "\n";