View source for Extended Table Markup

{{toc numerate=1}}

===Syntax===
#|
*| Character | Name | Alias names | Unicode | Wikipedia |*
|| ##""|""## | **Pipe** | vertical bar, vertical line | U+007C | wikipedia:Vertical_bar ||
|| ##""^""## | **Caret** | circumflex accent | U+005E | wikipedia:Caret ||
|#

#|(class=sticky)
|| ^ Syntax ^ Notes ||
^| Start | ##""#|""## | Besides beginning the table, this is also where the table's class is defined – for example, ##class="usertable"##. A table's "class" applies standard WackWiki formatting to that table.
##""#|(class="defaultcenter sticky" align=center)""## ||
^| Caption | ##""?|  |?""## | Required for accessibility purposes on data tables, and placed only between the table start and the first table row.  
##""?| Caption |?""##||
^| Col | ##""!|  |!""## | The ##<col>## HTML element defines one or more columns in a column group represented by its parent ##<colgroup>## element.  
##""!| |(bgcolor=yellow width=300px span=2)  |!""##||
^| Thead   | ##""*|  |*""## | head columns, entire row
##""*| Header 1 | Header 2 |*""## ||
^| Header cell | ##""^|""## | Optional. Each header cell starts with a new line and a ##""^|""##, or several header cells can be placed consecutively on the same line, separated by a single caret ##""^""##. 
##""^| Header | Cell ||""##
##""|| Cell ^ Header ||""## ||
^| Row | ##""||""## | To begin and end a new row of cells, use a double vertical bar ##""||""##.  
##""|| Cell 1 | Cell 2 ||""## ||
^| Cell | ##""|""## | To add a new cell in a row, start each new cell with a single vertical bar ##""|""##, several cells can be placed consecutively on the same line or a new line, separated by single vertical bar ##""|""##. ||
^| Attribute | ##""(attribute=value)""## | cell attributes
##""||(colspan=2 rowspan=2) 2x2 | 1x1 ||""##  ||
^| End | ##""|#""## | To end the table. ||
|#

The table cells as well as the caption are fully editable via wiki syntax.

====Attributes====
#|(class="defaultcenter col1left sticky")
!| |(bgcolor=red)  |(bgcolor=red) col |(bgcolor=red) caption |(bgcolor=red span=2) cell |  |!
||(rowspan=2) ^(rowspan=2) table ^(rowspan=2) col ^(rowspan=2) caption ^(colspan=2) cell ^(rowspan=2)  ||
*| th ^ td |*
^| align |(bgcolor=green) +   | –   |(bgcolor=green) +  |(bgcolor=green) +  |(bgcolor=green) +   |  ||
^| bgcolor |(bgcolor=green) + |(bgcolor=green) + |(bgcolor=green) +   |(bgcolor=green) +  |(bgcolor=green) +  |   ||
^| class |(bgcolor=green) + |(bgcolor=green) + |(bgcolor=green) +  |(bgcolor=green) +  |(bgcolor=green) +  |   ||
^| colspan | –   | –   | –   |(bgcolor=green) +  |(bgcolor=green) +  |   ||
^| id |(bgcolor=green) +  |(bgcolor=green) +  |(bgcolor=green) +  |(bgcolor=green) +  |(bgcolor=green) +  |   ||
^| rowspan | –  | –   | –   |(bgcolor=green) +   |(bgcolor=green) +  |   ||
^| scope | –   | –   | –   |(bgcolor=green) +  | –  |   ||
^| side | –   | –   |(bgcolor=green) +   | –   | –  |   ||
^| span | –   |(bgcolor=green) +   | –   | –   | –  |   ||
^| type |(bgcolor=green) +   |  –  | –   | –   | –  |   ||
^| width |(bgcolor=green) + |(bgcolor=green) +   | –   |(bgcolor=green) +  |(bgcolor=green) +  |   ||
^| valign | –  | –  | –  |(bgcolor=green) +  |(bgcolor=green) +  |   ||
|#

#|(class=sticky)
*| # | Attribute | Values | Notes |*
|| 1 ^ ##align## | ##center, left, right, justify## | Specifies the horizontal alignment of the data cell or places the table on the center, left or right side, allowing text and inline elements to wrap around it.
##(align=right)##

To align the data cells in an entire column or table, assign the appropriate CSS selectors using the ##class## attribute. ||
|| 2 ^ ##bgcolor##   | ##blue, red, green, x11colors## | Defines the background color of the data cell. The value is an HTML color; a color keyword.
##(bgcolor=green)## ||
|| 3 ^ ##class## | ##class_name## | available CSS selectors
  * table
    * ##alternate## alternating row shading
    * ##sticky## for sticky header
    * ##""default[left|center|right|top|middle|bottom]""##
    * ##""colN[left|center|right|top|middle|bottom]""## N stands for the column number
    * ##""col-N[left|center|right|top|middle|bottom]""## Align the cells in column N counting from the right.
##""#|(class="defaultcenter col1left col4right")""##  ||
|| 4 ^ ##colspan## | ##number## | Contains a non-negative integer value that indicates how many columns the data cell spans or extends.
##""||(colspan=2) 2x1 | 1x1 ||""##  ||
|| 5 ^ ##id## | ##id_name## | Defines a unique identifier (ID) which must be unique in the whole document.  
##(id=tbl1_summary)## ||
|| 6 ^ ##rowspan## | ##number## | Contains a non-negative integer value that indicates for how many rows the data cell spans or extends.
##""||(rowspan=2) 1x2 | 1x1 ||""##  ||
|| 7 ^ ##scope## | ##row, col, rowgroup, colgroup## | Optional. Defines the cells that the header (defined in the ##<th>##) element relates to. Possible enumerated values are:
  * ##row##: the header relates to all cells of the row it belongs to;
  * ##col##: the header relates to all cells of the column it belongs to;
  * ##rowgroup##: the header belongs to a rowgroup and relates to all of its cells;
  * ##colgroup##: the header belongs to a colgroup and relates to all of its cells.
##""^|(scope=row)""##  ||
|| 8 ^ ##side## | ##top, bottom## | Specifies on which side of the table the caption should be displayed. 
##""?|(side=bottom) Table Caption |?""## ||
|| 9 ^ ##span## | ##number## | Specifies the number of consecutive columns the ##<col>## element spans. 
##""!|(span=1) |(span=2) |!""## ||
|| 10 ^ ##type## | ##class_name## | Use a different table style, default is ##usertable## or ##dtable##.
##""#|(type=mytable)""## ||
|| 11 ^ ##valign## | ##top, middle, bottom## | Specifies the vertical alignment of the data cell. 
##(valign=middle)##||
|| 12 ^ ##width## | ##""number[px|%|em|rem]""## | Defines a recommended data cell width. 
##(width=50%)## ||
|#

====Colors====
  1. background colors
    * table header
    * row highlighting
    * subtle background colors
    * web-safe color


#|
||(bgcolor=green) green |(bgcolor=blue) blue ||
||(bgcolor=yellow) yellow |(bgcolor=red) red ||
|#

((https://www.color-hex.com/color-palette/70969 Highlighter Colors Color Palette))

lighter highlighting color for better contrast (?)

#||
||%%(colorbox bg_color="#b9ffc5" border_color="#fff") green%%
|%%(colorbox bg_color="#f8d4cc" border_color="#fff") red%%
|%%(colorbox bg_color="#cfe2ff" border_color="#fff") blue-subtle (primary)%%
||
||%%(colorbox bg_color="#e2e3e5" border_color="#fff") grey-subtle (secondary)%%
|%%(colorbox bg_color="#d1e7dd" border_color="#fff") green-subtle (success)%%
|%%(colorbox bg_color="#f8d7da" border_color="#fff") red-subtle (danger)%%
||
||%%(colorbox bg_color="#fff3cd" border_color="#fff") yellow-subtle (warning)%%
|%%(colorbox bg_color="#cff4fc" border_color="#fff") blue-subtle (info)%%
|
||
||#

#||
||%%(colorbox bg_color="#8cff32" border_color="#fff") hl green %% |%%(colorbox bg_color="#00ffd9" border_color="#fff") hl blue %% ||
||%%(colorbox bg_color="#ff6db7" border_color="#fff") hl red %% |%%(colorbox bg_color="#fbf719" border_color="#fff") hl green %% ||
||#

====Linebreaks====
====Spaces====
##""|| cell ||""##
##""||(pattern) cell ||""##

#|(class=sticky)
*|(width=30%) Pattern | Output |(width=30%) Note |*
|| ##""()""## |() | ||
|| ##""(hello)""## |(hello) | ||
|| ##""(pattern=value)""## |(pattern=value) | matches valid cell attribute pattern ||
|| ##""(pattern = value)""## |(pattern = value) | matches valid cell attribute pattern ||
|| ##""text""## |text | ||
|| ##""␣text""## | text | ignores heading space ||
|| ##""␣␣text""## |  text | text indention (##<div class="indent"></div>##) ||
|| ##""␣␣␣␣text""## |    text | text indention ||
|| ##""(align=right) text""## |(align=right) text | ||
|| ##""(align=justify) text""## |(align=justify) HTML preserves all whitespace in the source code as text nodes in the DOM, but CSS applies a default whitespace processing algorithm that collapses multiple spaces, tabs, and line breaks into a single space. | ||
|#

=====Table Space Ignored=====

**HTML and CSS whitespace handling** explains why browsers ignore leading spaces in table cells. HTML preserves all whitespace in the source code as text nodes in the DOM, but **CSS applies a default whitespace processing algorithm** that collapses multiple spaces, tabs, and line breaks into a single space. This behavior is consistent across all inline content, including table cells.

When you have leading spaces in a ##<td>## element, such as ##<td>   Hello</td>##, the browser processes the whitespace as follows:
  ***Leading and trailing whitespace** (spaces, tabs, line breaks) before and after text is ignored in rendering.
  ***Consecutive whitespace characters** (spaces, tabs, line feeds) are collapsed into a single space.
  *Only the **first space** between words is preserved; extra spaces are discarded.

This is not a bug—it's by design. The goal is to ensure readable text formatting without requiring developers to worry about code indentation affecting the displayed layout. For example, the following HTML:
%%(hl html)
<td>   Hello World!</td>
%%
is rendered as:
%%
Hello World!
%%
with only a single space between "Hello" and "World!".

=====Solutions to preserve spacing=====
If you need to display multiple spaces (e.g., for monospaced text or formatting), use one of these methods:
  * **Use ##white-space: pre##** in CSS to preserve all whitespace:
  %%(hl css)
  td {
    white-space: pre;
  }
  %%
  * **Use non-breaking spaces (##"" ""##)** to force visible spacing:
  %%(hl html)
  <td>  Hello</td>
  %%
  * **Wrap text in a ##<pre>## tag** if you want to preserve all formatting exactly as written.

This behavior applies uniformly across modern browsers and is part of the standard HTML and CSS specification.


===Backwards Compatibility===
The old colspan behavior is **not compatible** with the new ##colspan## or ##rowspan## attributes, it would add a ##colspan## where it not belongs.

It once expanded omitted cells at the end of a table row for the last cell to fit the previous rows columns.

By removing this behavior, existing col spans will default to their original colspan which is ##1##. Just add the new ##colspan=Number## attribute to the cell to restore the intended colspan.

%%(php)
<?php
// removed legacy colspan behavior
if (   ($i == $count)
	&& ($this->cols <> 0)
	&& ($count < $this->cols))
{
	$colspan = ' colspan="' . ($this->cols - $count + 1) . '"';
}
%%


===Documentation===

  1. update Table section in ((/Doc/English/Formatting Text Formatting page))
  1. add ((/Dev/NewFeatures/ExtendTableSyntax/TableMarkupGuide Table Markup Guide)) (draft)


===Resources===
  * https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Structuring_content/HTML_table_basics
  * https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Elements/table
  * https://html.spec.whatwg.org/multipage/tables.html#the-table-element
  * https://alistapart.com/article/web-typography-tables/
  * https://css-tricks.com/complete-guide-table-element/

===Examples===
%%
#| 
|| ^ Heading 1 ^ Heading 2 ||
^| Heading 3    | Row 1 Col 2          | Row 1 Col 3 ||
^| Heading 4    | no colspan | ||
^| Heading 5    | Row 3 Col 2          | Row 3 Col 3 ||
|#
%%

#| 
|| ^ Heading 1 ^ Heading 2 ||
^| Heading 3    | Row 1 Col 2          | Row 1 Col 3 ||
^| Heading 4    | no colspan | ||
^| Heading 5    | Row 3 Col 2          | Row 3 Col 3 ||
|#

%%
#|
?| Fruit production in the last **two** years |?
*| |(colspan=2) Apples |(colspan=2) Pears |*
*| | 2025 | 2026 | 2025 | 2026 |*
^| Mary | 300Kg | 320Kg | 400kg | 280Kg ||
^| John | 400Kg | 630Kg | 210Kg | 300Kg ||
|#
%%

#|
?| Fruit production in the last **two** years |?
*| |(colspan=2) Apples |(colspan=2) Pears |*
*| | 2025 | 2026 | 2025 | 2026 |*
^| Mary | 300Kg | 320Kg | 400kg | 280Kg ||
^| John | 400Kg | 630Kg | 210Kg | 300Kg ||
|#

%%
#|
||(align=left width=50%) left |(rowspan=3 valign=top) top |(rowspan=3 valign=middle) middle |(rowspan=3 valign=bottom) bottom ||
||(align=center) center ||
||(align=right) right ||
|#
%%

#|
||(align=left width=50%) left |(rowspan=3 valign=top) top |(rowspan=3 valign=middle) middle |(rowspan=3 valign=bottom) bottom ||
||(align=center) center ||
||(align=right) right ||
|#

%%
#|
||(rowspan=2) 2 lines | line 1 ||
|| line 2 ||
||(colspan=2) line 3, 2 columns broad ||
|#
%%

#|
||(rowspan=2) 2 lines | line 1 ||
|| line 2 ||
||(colspan=2) line 3, 2 columns broad ||
|#


%%
#|
^|(colspan=2 rowspan=2) 2x2 |(colspan=2) 2x1 |(rowspan=2) 1x2 ||
||(rowspan=2) 1x2 | 1x1 ||
|| 1x1 | 1x1 |(colspan=2) 2x1 ||
|#
%%

#|
^|(colspan=2 rowspan=2) 2x2 |(colspan=2) 2x1 |(rowspan=2) 1x2 ||
||(rowspan=2) 1x2 | 1x1 ||
|| 1x1 | 1x1 |(colspan=2) 2x1 ||
|#


#|
^| 1 | 1 ||
^| 2 | 2 | 4 ||
^| 3 | 3 | 6 | 9 ||
^| 4 | 4 | 8 | 12 | 16 ||
^| 5 | 5 | 10 | 15 | 20 | 25 ||
^| 6 | 6 | 12 | 18 | 24 | 30 | 36 ||
^| 7 | 7 | 14 | 21 | 28 | 35 | 42 | 49 ||
^| 8 | 8 | 16 | 24 | 32 | 40 | 48 | 56 | 64 ||
^| 9 | 9 | 18 | 27 | 36 | 45 | 54 | 63 | 72 | 81 ||
*| × | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |*
|#