PhantomCaleb (talk | contribs) mNo edit summary |
PhantomCaleb (talk | contribs) No edit summary |
||
(8 intermediate revisions by the same user not shown) | |||
Line 4: | Line 4: | ||
local utilsFunction = require("Module:UtilsFunction") |
local utilsFunction = require("Module:UtilsFunction") |
||
local utilsLayout = require("Module:UtilsLayout/Tabs") |
local utilsLayout = require("Module:UtilsLayout/Tabs") |
||
+ | local utilsNumber = require("Module:UtilsNumber") |
||
local utilsString = require("Module:UtilsString") |
local utilsString = require("Module:UtilsString") |
||
local utilsTable = require("Module:UtilsTable") |
local utilsTable = require("Module:UtilsTable") |
||
Line 85: | Line 86: | ||
function h.resolveShorthand(data) |
function h.resolveShorthand(data) |
||
+ | data = mw.clone(data) |
||
− | local fullData = { |
||
+ | if data.headers then |
||
⚫ | |||
⚫ | |||
⚫ | |||
− | + | header = true, |
|
− | + | cells = data.headers |
|
− | + | }) |
|
+ | end |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | header = row.header, |
||
− | footer = row.footer, |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
local cell = h.resolveShorthandCell(cell) |
local cell = h.resolveShorthandCell(cell) |
||
− | + | data.rows[i].cells[j] = cell |
|
if cell then |
if cell then |
||
cell.styles = utilsTable.merge(row.styles or {}, cell.styles or {}) |
cell.styles = utilsTable.merge(row.styles or {}, cell.styles or {}) |
||
end |
end |
||
end |
end |
||
− | if utilsTable.isEmpty( |
+ | if utilsTable.isEmpty(data.rows[i]) then |
− | + | data.rows[i] = nil |
|
end |
end |
||
end |
end |
||
− | return |
+ | return data |
end |
end |
||
function h.resolveShorthandCell(cell) |
function h.resolveShorthandCell(cell) |
||
Line 155: | Line 149: | ||
function h.hideEmptyColumns(data) |
function h.hideEmptyColumns(data) |
||
local totalColumns = h.countTotalColumns(data.rows) |
local totalColumns = h.countTotalColumns(data.rows) |
||
− | local |
+ | local emptyCellsPerColumn = {} |
− | for |
+ | for i, row in ipairs(data.rows) do |
− | for |
+ | for j, cell in ipairs(row.cells) do |
+ | emptyCellsPerColumn[j] = emptyCellsPerColumn[j] or 0 |
||
if (not cell.header and not cell.footer) and h.isCellEmpty(cell) then |
if (not cell.header and not cell.footer) and h.isCellEmpty(cell) then |
||
− | + | emptyCellsPerColumn[j] = emptyCellsPerColumn[j] + 1 |
|
end |
end |
||
end |
end |
||
for i in utilsFunction.range(#row.cells + 1, totalColumns) do |
for i in utilsFunction.range(#row.cells + 1, totalColumns) do |
||
− | + | emptyCellsPerColumn[i] = emptyCellsPerColumn[i] + 1 |
|
end |
end |
||
end |
end |
||
− | data = mw.clone(data) |
+ | local data = mw.clone(data) |
− | local removedColumns = 0 |
||
local headerRows = utilsTable.filter(data.rows, "header") |
local headerRows = utilsTable.filter(data.rows, "header") |
||
local footerRows = utilsTable.filter(data.rows, "footer") |
local footerRows = utilsTable.filter(data.rows, "footer") |
||
Line 173: | Line 167: | ||
for i, row in ipairs(data.rows) do |
for i, row in ipairs(data.rows) do |
||
for j, cell in ipairs(row.cells) do |
for j, cell in ipairs(row.cells) do |
||
− | if |
+ | if emptyCellsPerColumn[j] == totalRows then |
+ | row.cells[j] = nil |
||
⚫ | |||
end |
end |
||
end |
end |
||
⚫ | |||
end |
end |
||
return data |
return data |
||
Line 284: | Line 279: | ||
), |
), |
||
utilsTable.zip, |
utilsTable.zip, |
||
+ | utilsTable._map(utilsTable._padNils(utilsNumber.MIN)), |
||
utilsTable._map(utilsTable.max), |
utilsTable._map(utilsTable.max), |
||
} |
} |
||
Line 304: | Line 300: | ||
data = { |
data = { |
||
definitions = { |
definitions = { |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | name = "hideEmptyRows", |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
rowOptions = { |
rowOptions = { |
||
type = "record", |
type = "record", |
||
Line 354: | Line 323: | ||
}, |
}, |
||
rows = { |
rows = { |
||
− | + | type = "array", |
|
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
{ |
{ |
||
type = "record", |
type = "record", |
||
properties = { |
properties = { |
||
{ |
{ |
||
− | name = " |
+ | name = "cells", |
⚫ | |||
type = "array", |
type = "array", |
||
− | items = { _ref = "#/definitions/ |
+ | items = { _ref = "#/definitions/cell" } |
− | } |
+ | }, |
− | } |
+ | }, |
− | } |
+ | } |
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | allOf = { |
||
⚫ | |||
⚫ | |||
} |
} |
||
}, |
}, |
||
Line 422: | Line 385: | ||
}, |
}, |
||
{ |
{ |
||
⚫ | |||
_ref = "#/definitions/rows", |
_ref = "#/definitions/rows", |
||
desc = "Subvidisions for the cell. Think of it as a table within a table." |
desc = "Subvidisions for the cell. Think of it as a table within a table." |
||
Line 433: | Line 397: | ||
}, |
}, |
||
⚫ | |||
required = true, |
required = true, |
||
desc = "A Lua table representing the desired wikitable.", |
desc = "A Lua table representing the desired wikitable.", |
||
− | + | properties = { |
|
⚫ | |||
⚫ | |||
− | + | name = "sortable", |
|
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | { |
||
⚫ | |||
⚫ | |||
+ | items = { type = "string" }, |
||
+ | desc = "An array of strings to serve as a header row.", |
||
⚫ | |||
+ | { |
||
⚫ | |||
⚫ | |||
+ | type = "array", |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
} |
} |
||
}, |
}, |
||
Line 521: | Line 523: | ||
args = { |
args = { |
||
{ |
{ |
||
⚫ | |||
⚫ | |||
− | {'cell1', 'cell2', 'cell3'} |
+ | {'cell1', 'cell2', 'cell3'} |
− | } |
+ | }, |
⚫ | |||
⚫ | |||
⚫ | |||
+ | }, |
||
}, |
}, |
||
{ |
{ |
||
Line 530: | Line 534: | ||
args = { |
args = { |
||
{ |
{ |
||
⚫ | |||
− | {"cell | 1", "cell |} 2", "cell {| 3"}, |
+ | {"cell | 1", "cell |} 2", "cell {| 3"}, |
⚫ | |||
⚫ | |||
⚫ | |||
}, |
}, |
||
}, |
}, |
||
Line 539: | Line 545: | ||
{ |
{ |
||
rows = { |
rows = { |
||
− | { |
+ | { |
⚫ | |||
⚫ | |||
− | + | colspan = 2, |
|
⚫ | |||
⚫ | |||
− | + | }, |
|
− | + | { |
|
− | + | colspan = 3, |
|
− | + | content = "spans 3 columns", |
|
⚫ | |||
⚫ | |||
− | colspan = 3, |
||
⚫ | |||
− | }, |
||
}, |
}, |
||
}, |
}, |
||
{ |
{ |
||
− | + | { |
|
− | + | colspan = -1, |
|
− | + | content = "spans all columns", |
|
− | content = "spans all columns", |
||
− | }, |
||
}, |
}, |
||
}, |
}, |
||
}, |
}, |
||
⚫ | |||
} |
} |
||
}, |
}, |
||
Line 573: | Line 573: | ||
hideEmptyColumns = true, |
hideEmptyColumns = true, |
||
rows = { |
rows = { |
||
− | { |
+ | {"row1", "", "row1"}, |
− | { |
+ | {"row2", "", "row2"}, |
− | + | }, |
|
+ | headers = {"not empty", "empty", "not empty"}, |
||
− | } |
||
} |
} |
||
} |
} |
Revision as of 16:16, 15 August 2020
This module exports the following functions.
table
table(data)
Parameters
data
- A Lua table representing the desired wikitable.
[sortable]
- If
true
renders a table that can be sorted by any of its columns. [hideEmptyColumns]
- If
true
, columns that are completely empty (except for header and footer rows) are omitted. [hideEmptyRows]
- If
true
, rows that are completely empty (except for header cells) are omitted. [styles]
- Key-value pairs of CSS properties to apply to the
<table>
element. [headers]
- An array of strings to serve as a header row.
rows
Returns
- Wikitext for the table using XHTML syntax.
Examples
# | Input | Result | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Basic table with header and footer | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
1 | table({
rows = {
{
header = true,
cells = {"column1", "column2", "column3"},
},
{
cells = {"cell1", "cell2", "cell3"},
},
{
cells = {"cell4", "cell5", "cell6"},
},
{
footer = true,
cells = {"foot1", "foot2", "foot2"},
},
},
})
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Shorthand syntax | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
2 | table({
headers = {"column1", "column2", "column3"},
rows = {
{"cell1", "cell2", "cell3"},
},
})
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Works with pipe characters | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
3 | table({
rows = {
{"cell | 1", "cell |} 2", "cell {| 3"},
},
})
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Cell spanning multiple columns | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
4 | table({
headers = {"col1", "col2", "col3", "col4", "col5"},
rows = {
{
{
colspan = 2,
content = "spans 2 columns",
},
{
colspan = 3,
content = "spans 3 columns",
},
},
{
{
colspan = -1,
content = "spans all columns",
},
},
},
})
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Option to hide columns when they're completely empty except for headers/footers | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
5 | table({
hideEmptyRows = true,
hideEmptyColumns = true,
rows = {
{"row1", "", "row1"},
{"row2", "", "row2"},
},
headers = {"not empty", "empty", "not empty"},
})
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Option to hide rows when they're completely empty except for headers | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
6 | table({
hideEmptyRows = true,
rows = {
{
{
header = true,
content = "Header1",
},
"not empty",
},
{
{
header = true,
content = "Header2",
},
"",
},
{},
},
})
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Table styles are applied at the table level. Cell styles can be specified individually, or once for the entire row. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
7 | table({
rows = {
{"centered", "centered"},
{
cells = {
{ content = "left-aligned" },
{
content = "right-aligned",
styles = { ["text-align"] = "right" },
},
},
styles = { ["text-align"] = "left" },
},
},
styles = {
["text-align"] = "center",
width = "20em",
},
})
|
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Individual cells subdivided into multiple columns and rows | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
8 | table({
rows = {
{
header = true,
cells = {"Column1", "Column2", "Column3"},
},
{
"A",
{
{"B1"},
{"B2"},
},
"C",
},
{
{
{"D1", "D2"},
},
{
{"E1"},
{
{
content = "E2",
header = true,
},
"E3",
},
},
{
{"F1"},
{"F2"},
{"F3"},
},
},
{
{
{"G1", "G2", "G3"},
},
"H",
{
{},
},
},
},
styles = { ["text-align"] = "center" },
})
|
|
tabbedTable
tabbedTable(data)
Parameters
data
[headerRows]
- Header rows common to every tab.
[headerRows]
- Footer rows common to every tab.
tabs
Returns
- A series of wikitables displayed using tabs. Useful for representing data with three dimensions, or data with too many columns.
Examples
# | Input | Result | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Tabbed table with shared headers and footers | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
9 | tabbedTable({
headerRows = {
{"col1", "col2", "col3"},
},
tabs = {
{
label = "tab1",
rows = {
{"cell1", "cell2", "cell3"},
{"cell4", "cell5", "cell6"},
},
},
{
label = "tab2",
rows = {
{"cell7", "cell8", "cell9"},
{"cell10", "cell11", "cell12"},
},
},
},
footerRows = {
{"foo12", "foot2", "foot3"},
},
})
| tab1tab2
|
local p = {}
local h = {}
local utilsFunction = require("Module:UtilsFunction")
local utilsLayout = require("Module:UtilsLayout/Tabs")
local utilsNumber = require("Module:UtilsNumber")
local utilsString = require("Module:UtilsString")
local utilsTable = require("Module:UtilsTable")
function p.table(data)
data = h.resolveShorthand(data)
if data.hideEmptyColumns then
data = h.hideEmptyColumns(data)
end
if data.hideEmptyRows then
data = h.hideEmptyRows(data)
end
data = h.splitCells(data)
return h.createTable(data)
end
function p.tabbedTable(data)
local tabs = {}
local headerRows = data.headerRows or {}
local footerRows = data.footerRows or {}
for i, headerRow in ipairs(headerRows) do
headerRow.header = true
end
for i, footerRow in ipairs(footerRows) do
footerRow.footer = true
end
for i, tabData in ipairs(data.tabs) do
local tabRows = utilsTable.concat(headerRows, tabData.rows, footerRows)
table.insert(tabs, {
label = tabData.label,
content = p.table({ rows = tabRows })
})
end
return utilsLayout.tabs(tabs)
end
function h.createTable(data)
local html = mw.html.create("table"):addClass("wikitable")
for _, row in ipairs(data.rows) do
html:node(h.createRow(row))
end
local margins
if data.align == "center" then
margins = {
margin = "0 auto"
}
elseif data.align == "right" then
margins = {
["margin-left"] = "auto"
}
end
html:css(margins or {})
html:css(data.styles or {})
html:addClass(data.sortable and "sortable" or nil)
return tostring(html)
end
function h.createRow(row)
local html = mw.html.create("tr")
for _, cell in ipairs(row.cells) do
local cellTag = (row.header or row.footer or cell.header or cell.footer) and "th" or "td"
local colspan = cell.colspan
local rowspan = cell.rowspan
if colspan and colspan < 0 then
colspan = 1000
end
if rowspan and rowspan < 0 then
rowspan = 1000
end
html:tag(cellTag)
:attr("colspan", colspan)
:attr("rowspan", rowspan)
:css(cell.styles or {})
:wikitext(mw.getCurrentFrame():preprocess(cell.content))
:done()
end
return tostring(html)
end
function h.resolveShorthand(data)
data = mw.clone(data)
if data.headers then
table.insert(data.rows, 1, {
header = true,
cells = data.headers
})
end
for i, row in ipairs(data.rows) do
row.cells = row.cells or utilsTable.ivalues(row)
for j, cell in ipairs(row.cells) do
local cell = h.resolveShorthandCell(cell)
data.rows[i].cells[j] = cell
if cell then
cell.styles = utilsTable.merge(row.styles or {}, cell.styles or {})
end
end
if utilsTable.isEmpty(data.rows[i]) then
data.rows[i] = nil
end
end
return data
end
function h.resolveShorthandCell(cell)
if type(cell) == "string" or type(cell) == "number" or type(cell) == "boolean" then
return {
content = cell
}
end
if type(cell) == "table" and utilsTable.isEmpty(cell) then
return nil
end
if type(cell) == "table" and cell.content and not utilsTable.isArray(cell.content) then
return cell
end
if not cell.content then
cell = {
content = utilsTable.ivalues(cell)
}
end
if utilsTable.isArray(cell.content) then
for i, subrow in ipairs(cell.content) do
table.remove(cell, i)
cell.content[i] = utilsTable.map(subrow, h.resolveShorthandCell)
end
end
return cell
end
function h.hideEmptyRows(data)
for i, row in ipairs(data.rows) do
local isNonEmptyCell = function(cell)
return not cell.header and not h.isCellEmpty(cell)
end
local nonEmptyCells = utilsTable.filter(row.cells, isNonEmptyCell)
if #nonEmptyCells == 0 then
table.remove(data.rows, i)
end
end
return data
end
function h.hideEmptyColumns(data)
local totalColumns = h.countTotalColumns(data.rows)
local emptyCellsPerColumn = {}
for i, row in ipairs(data.rows) do
for j, cell in ipairs(row.cells) do
emptyCellsPerColumn[j] = emptyCellsPerColumn[j] or 0
if (not cell.header and not cell.footer) and h.isCellEmpty(cell) then
emptyCellsPerColumn[j] = emptyCellsPerColumn[j] + 1
end
end
for i in utilsFunction.range(#row.cells + 1, totalColumns) do
emptyCellsPerColumn[i] = emptyCellsPerColumn[i] + 1
end
end
local data = mw.clone(data)
local headerRows = utilsTable.filter(data.rows, "header")
local footerRows = utilsTable.filter(data.rows, "footer")
local totalRows = #data.rows - (math.max(#headerRows, #footerRows))
for i, row in ipairs(data.rows) do
for j, cell in ipairs(row.cells) do
if emptyCellsPerColumn[j] == totalRows then
row.cells[j] = nil
end
end
row.cells = utilsTable.compact(row.cells)
end
return data
end
-- Cell is empty if:
-- its content is nil or the empty string
-- it has subdivisons where all the rows are empty
function h.isCellEmpty(cell)
if type(cell.content) == "string" and utilsString.isBlank(cell.content) then
return true
end
if type(cell.content) == "table" then
for _, subRow in ipairs(cell.content) do
for _, subCell in ipairs(subRow) do
if not utilsString.isBlank(cell.subCell) then
return true
end
end
end
end
return false
end
function h.countTotalColumns(rows)
local maxColumns = 0
for _, row in ipairs(rows) do
maxColumns = math.max(maxColumns, #row.cells)
end
return maxColumns
end
function h.splitCells(data)
data = h.normalize(data)
data = h.splitRows(data)
data = h.applyColspans(data)
data = h.flattenCellGroups(data)
return data
end
function h.normalize(data)
for i, row in ipairs(data.rows) do
for j, cell in ipairs(row.cells) do
data.rows[i].cells[j] = h.normalizeCell(cell)
end
end
return data
end
function h.normalizeCell(cell)
if utilsTable.isArray(cell.content) then
return cell.content
end
return {{cell}}
end
function h.splitRows(data)
data.rows = utilsTable.flatMap(data.rows, h.splitRow)
return data
end
function h.splitRow(row)
local splitRows = utilsTable.zip(row.cells, {})
local cellSubrows = utilsTable.zip(splitRows)
for i, subrows in ipairs(cellSubrows) do
local isNotEmpty = utilsFunction.negate(utilsTable.isEmpty)
local lastSubrow, lastSubrowIndex = utilsTable.findLast(subrows, isNotEmpty)
if lastSubrow then
local rowspan = #subrows - lastSubrowIndex + 1
h.applyRowspan(lastSubrow, rowspan)
end
end
local rows = {}
for i, splitRow in ipairs(splitRows) do
rows[i] = {
header = row.header,
footer = row.footer,
row = row.styles,
cells = splitRow,
}
end
return rows
end
function h.applyRowspan(cellGroup, rowspan)
if rowspan <= 1 or not cellGroup then
return
end
for i, cell in ipairs(cellGroup) do
if cell.rowspan and cell.rowspan > 1 then
cell.rowspan = rowspan + cell.rowspan
else
cell.rowspan = rowspan
end
end
end
function h.applyColspans(data)
local colspansPerColumn = h.getColspansForEachColumn(data)
for i, row in ipairs(data.rows) do
for j, cellGroup in ipairs(row.cells) do
h.applyColspan(cellGroup, colspansPerColumn[j])
end
end
return data
end
function h.getColspansForEachColumn(data)
return utilsFunction.pipe(data.rows) {
utilsTable._map("cells"),
utilsTable._map(
utilsTable._map(utilsTable.size)
),
utilsTable.zip,
utilsTable._map(utilsTable._padNils(utilsNumber.MIN)),
utilsTable._map(utilsTable.max),
}
end
function h.applyColspan(cellGroup, colspan)
if #cellGroup > 0 and #cellGroup < colspan then
cellGroup[#cellGroup].colspan = colspan - #cellGroup + 1
end
end
function h.flattenCellGroups(data)
for i, row in ipairs(data.rows) do
row.cells = utilsTable.flatten(row.cells)
end
return data
end
p.Schemas = {
table = {
data = {
definitions = {
rowOptions = {
type = "record",
properties = {
{
name = "header",
type = "boolean",
desc = "If <code>true</code> renders all cells in row as <code><nowiki><th></nowiki></code> elements.",
},
{
name = "footer",
type = "boolean",
desc = "If <code>true</code> renders all cells in row as <code><nowiki><th></nowiki></code> elements.",
},
{
name = "styles",
type = "map",
keys = { type = "string" },
values = { type = "string" },
desc = "Key-value pairs of CSS properties to apply to each cell in the row.",
},
},
},
rows = {
type = "array",
items = { _ref = "#/definitions/row" },
},
row = {
allOf = {
{ _ref = "#/definitions/rowOptions" },
{
type = "record",
properties = {
{
name = "cells",
type = "array",
items = { _ref = "#/definitions/cell" }
},
},
}
}
},
cells = {
type = "record",
properties = {
{
name = "cells",
type = "array",
items = { _ref = "#/definitions/cell" }
},
},
},
cell = {
oneOf = {
{
type = "record",
properties = {
{
name = "header",
type = "boolean",
desc = "If <code>true</code>, renders the cell as a <code><nowiki><th></nowiki></code> element.",
},
{
name = "colspan",
type = "number",
},
{
name = "rowspan",
type = "number",
},
{
name = "styles",
type = "map",
keys = { type = "string" },
values = { type = "string" },
desc = "Key-value pairs of CSS properties to apply to the cell. Overrides any conflicting row styles.",
},
{
name = "content",
required = true,
oneOf = {
{
type = "string",
desc = "Wikitext content for the cell.",
},
{
type = "array",
_ref = "#/definitions/rows",
desc = "Subvidisions for the cell. Think of it as a table within a table."
}
}
}
},
}
}
},
},
type = "record",
required = true,
desc = "A Lua table representing the desired wikitable.",
properties = {
{
name = "sortable",
type = "boolean",
desc = "If <code>true</code> renders a table that can be sorted by any of its columns."
},
{
name = "hideEmptyColumns",
type = "boolean",
desc = "If <code>true</code>, columns that are completely empty (except for header and footer rows) are omitted.",
},
{
name = "hideEmptyRows",
type = "boolean",
desc = "If <code>true</code>, rows that are completely empty (except for header cells) are omitted.",
},
{
name = "styles",
type = "map",
keys = { type = "string" },
values = { type = "string" },
desc = "Key-value pairs of CSS properties to apply to the <code><nowiki><table></nowiki></code> element.",
},
{
name = "headers",
type = "array",
items = { type = "string" },
desc = "An array of strings to serve as a header row.",
},
{
name = "rows",
required = true,
type = "array",
items = {
allOf = {
{ _ref = "#/definitions/rowOptions" },
{ _ref = "#/definitions/cells" },
}
},
},
},
}
},
tabbedTable = {
data = {
type = "record",
required = true,
properties = {
{
name = "headerRows",
type = "any",
typeLabel = "rows",
desc = "Header rows common to every tab.",
},
{
name = "headerRows",
type = "any",
typeLabel = "rows",
desc = "Footer rows common to every tab.",
},
{
name = "tabs",
required = true,
allOf = {
{
type = "record",
properties = {
{
name = "label",
type = "string",
required = true,
desc = "Tab label",
},
{
name = "rows",
type = "any",
required = true,
typeLabel = "rows",
desc = "Table rows for the tab. See {{Sect|table}} for format.",
}
},
},
}
}
}
},
},
}
p.Documentation = {
table = {
params = {"data"},
returns = "Wikitext for the table using {{mediawiki|Help:Table#Other table syntax|XHTML syntax}}.",
cases = {
resultOnly = true,
{
desc = "Basic table with header and footer",
args = {
{
rows = {
{
header = true,
cells = { 'column1', 'column2', 'column3'},
},
{
cells = {'cell1', 'cell2', 'cell3'},
},
{
cells = {'cell4', 'cell5', 'cell6'},
},
{
footer = true,
cells = {'foot1', 'foot2', 'foot2'},
},
},
},
},
},
{
desc = "Shorthand syntax",
args = {
{
rows = {
{'cell1', 'cell2', 'cell3'}
},
headers = {'column1', 'column2', 'column3'},
},
},
},
{
desc = "Works with pipe characters",
args = {
{
rows = {
{"cell | 1", "cell |} 2", "cell {| 3"},
},
}
},
},
{
desc = "Cell spanning multiple columns",
args = {
{
rows = {
{
{
colspan = 2,
content = "spans 2 columns",
},
{
colspan = 3,
content = "spans 3 columns",
},
},
{
{
colspan = -1,
content = "spans all columns",
},
},
},
headers = {"col1", "col2", "col3", "col4", "col5"}
}
},
},
{
desc = "Option to hide columns when they're completely empty except for headers/footers",
args = {
{
hideEmptyRows = true,
hideEmptyColumns = true,
rows = {
{"row1", "", "row1"},
{"row2", "", "row2"},
},
headers = {"not empty", "empty", "not empty"},
}
}
},
{
desc = "Option to hide rows when they're completely empty except for headers",
args = {
{
hideEmptyRows = true,
rows = {
{ { header = true, content = "Header1"}, "not empty"},
{ { header = true, content = "Header2" }, "" },
{ },
}
}
}
},
{
desc = "Table styles are applied at the table level. Cell styles can be specified individually, or once for the entire row.",
args = {
{
styles = {
["width"] = "20em",
["text-align"] = "center",
},
rows = {
{ "centered", "centered" },
{
styles = {
["text-align"] = "left"
},
cells = {
{ content = "left-aligned" },
{
content = "right-aligned",
styles = {
["text-align"] = "right",
}
},
},
},
},
},
},
},
{
desc = "Individual cells subdivided into multiple columns and rows",
args = {
{
styles = { ["text-align"] = "center" },
rows = {
{
header = true,
cells = {"Column1", "Column2", "Column3"},
},
{
"A",
{
{"B1"},
{"B2"},
},
"C"
},
{
{
{"D1", "D2"}
},
{
{"E1"},
{{ content = "E2", header = true }, "E3"},
},
{
{"F1"},
{"F2"},
{"F3"},
}
},
{
{
{ "G1", "G2", "G3"}
},
"H",
{{}},
}
},
},
},
}
}
},
tabbedTable = {
params = {"data"},
returns = "A series of wikitables displayed using tabs. Useful for representing data with three dimensions, or data with too many columns.",
cases = {
resultOnly = true,
{
desc = "Tabbed table with shared headers and footers",
args = {
{
headerRows = {
{"col1", "col2", "col3"}
},
footerRows = {
{"foo12", "foot2", "foot3"}
},
tabs = {
{
label = "tab1",
rows = {
{'cell1', 'cell2', 'cell3'},
{'cell4', 'cell5', 'cell6'},
}
},
{
label = "tab2",
rows = {
{'cell7', 'cell8', 'cell9'},
{'cell10', 'cell11', 'cell12'},
},
},
},
},
},
},
},
},
}
return p