Modul:Diagram
Zur Navigation springen
Zur Suche springen
Dokumentation Die folgende Dokumentation stammt von der Seite Modul:Diagram/Dokumentation. (bearbeiten | Versionsgeschichte)
Siehe auch die englische Modulseite: Module:Diagram. Sie enthält möglicherweise umfassendere oder aktuellere Informationen.
Dieses Modul stellt die Funktionalität von {{diagramm}}. Diese Vorlage dient hauptsächlich dazu, Herstellungsbäume im Wiki darzustellen. Das Modul erstellt eine Tabelle, deren Zellränder die Linien im Diagramm erzeugen und so den Effekt eines Baumes hervorrufen. Hinweise zur Verwendung der Vorlage sind auf der Vorlagenseite, {{diagramm}}, zu finden.
Die Idee basiert auf der Vorlage „Family tree“ im The Witcher Wiki. Westgrass hat sie grundlegend optimiert und die Funktionalität in dieses Modul überführt.
--------------------------------------------------------------------------------
--
-- =============================================================================
--
-- Module:Diagram
--
-- Rendering a family tree-like diagram
--
-- =============================================================================
--
-- Code annotations:
-- This module is documented according to LuaCATS (Lua Comment and Type System).
-- LuaCATS comments are prefixed with three dashes (---) and use Markdown syntax.
-- For a full list of annotations, see the following link:
-- https://luals.github.io/wiki/annotations/
--
--------------------------------------------------------------------------------
local trim = mw.text.trim
---Holds the arguments from the template call.
---@type table<string, string>
local inputArgs
---Return a trimmed version of the value of the template parameter with the specified `key`.
---Return `nil` if the parameter is empty or unset.
---@param key string|integer
---@return string?
local function getArg(key)
local value = inputArgs[key]
if not value then
return nil
end
value = trim(value)
if value == '' then
return nil
end
return value
end
---Combine all the buffered cells during this row.
---@param row1 string Buffer from the iteration
---@param row2 string Buffer from the iteration
---@return string row HTML output for this row
local function processRow(row1, row2)
return '<tr class="x"> ' .. row1 .. '</tr><tr class="y">' .. row2 .. '</tr>'
end
---Merge the common styles for all boxes (from the `boxstyle` argument) with the
---styles for this current box.
---@param commonBoxstyle string
---@param arg string Current box name
---@return string
local function mergeStyles(commonBoxstyle, arg)
return table.concat({
commonBoxstyle,
getArg(arg .. '_boxstyle') or getArg(arg .. '_style') or getArg(arg .. '_css')
}, ';')
end
---Table cells for connectors, i.e. horizontal and vertical lines, line corners,
---crossings, etc.
local connectorCells = {
['_'] = {
row1 = '<td class="l nr nb"></td><td class="l"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['-'] = {
row1 = '<td colspan="2" class="l sb"></td>',
row2 = '<td class="l nr"></td><td class="l"></td>',
},
['I'] = {
row1 = '<td rowspan="2" class="l sr"></td><td class="l nb"></td>',
row2 = '<td class="l"></td>',
},
[','] = {
row1 = '<td class="l cf"></td><td class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['v'] = {
row1 = '<td colspan="2" class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['.'] = {
row1 = '<td class="l sb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
[')'] = {
row1 = '<td rowspan="2" class="l sr"></td><td class="l sb"></td>',
row2 = '<td class="l"></td>',
},
['+'] = {
row1 = '<td class="l sr sb"></td><td class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['('] = {
row1 = '<td class="l sb sr"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
['`'] = {
row1 = '<td class="l sr"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['^'] = {
row1 = '<td class="l sr sb"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
["'"] = {
row1 = '<td class="l sr sb"></td><td class="l"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['~'] = {
row1 = '<td colspan="2" class="l db"></td>',
row2 = '<td class="l nr"></td><td class="l"></td>',
},
[':'] = {
row1 = '<td rowspan="2" class="l dr"></td><td class="l nb"></td>',
row2 = '<td class="l"></td>',
},
['F'] = {
row1 = '<td class="l cf"></td><td class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['V'] = {
row1 = '<td colspan="2" class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['7'] = {
row1 = '<td class="l db"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['D'] = {
row1 = '<td rowspan="2" class="l dr"></td><td class="l db"></td>',
row2 = '<td class="l"></td>',
},
['X'] = {
row1 = '<td class="l dr db"></td><td class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['C'] = {
row1 = '<td class="l db dr"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['L'] = {
row1 = '<td class="l dr"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['A'] = {
row1 = '<td class="l dr db"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['J'] = {
row1 = '<td class="l dr db"></td><td class="l"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['r'] = {
row1 = '<td class="l cf"></td><td class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['y'] = {
row1 = '<td colspan="2" class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['n'] = {
row1 = '<td class="l db"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
[']'] = {
row1 = '<td rowspan="2" class="l sr"></td><td class="l db"></td>',
row2 = '<td class="l"></td>',
},
['$'] = {
row1 = '<td class="l sr db"></td><td class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['['] = {
row1 = '<td class="l db sr"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
['c'] = {
row1 = '<td class="l sr"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['h'] = {
row1 = '<td class="l sr db"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['j'] = {
row1 = '<td class="l sr db"></td><td class="l"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['p'] = {
row1 = '<td class="l cf"></td><td class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['u'] = {
row1 = '<td colspan="2" class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['q'] = {
row1 = '<td class="l sb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['E'] = {
row1 = '<td rowspan="2" class="l dr"></td><td class="l sb"></td>',
row2 = '<td class="l"></td>',
},
['x'] = {
row1 = '<td class="l dr sb"></td><td class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['3'] = {
row1 = '<td class="l sb dr"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['b'] = {
row1 = '<td class="l dr"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['t'] = {
row1 = '<td class="l dr sb"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['d'] = {
row1 = '<td class="l dr sb"></td><td class="l"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['/'] = {
row1 = '<td class="l dr db"></td><td class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['Y'] = {
row1 = '<td class="l dr sb"></td><td class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['\\'] = {
row1 = '<td class="l dr sb"></td><td class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['B'] = {
row1 = '<td class="l sr db"></td><td class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['G'] = {
row1 = '<td class="l sr sb"></td><td class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['R'] = {
row1 = '<td class="l sr db"></td><td class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['U'] = {
row1 = '<td class="l sr sb"></td><td class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['4'] = {
row1 = '<td class="l sr sb"></td><td class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['!'] = {
row1 = '<td class="l sr nb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['i'] = {
row1 = '<td class="l dr nb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
['<'] = {
row1 = '<td class="l sb nr"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['>'] = {
row1 = '<td class="l db nr"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['9'] = {
row1 = '<td class="l sr nb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l"></td>',
},
['6'] = {
row1 = '<td colspan="2" class="l nb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['&'] = {
row1 = '<td class="l sb nr"></td><td class="l"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['?'] = {
row1 = '<td class="l nr"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['"'] = {
row1 = '<td class="l dr nb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l"></td>',
},
[';'] = {
row1 = '<td colspan="2" class="l nb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['a'] = {
row1 = '<td class="l db nr"></td><td class="l"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['e'] = {
row1 = '<td class="l nr"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['M'] = {
row1 = '<td class="l dr db"></td><td class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['W'] = {
row1 = '<td class="l sr db"></td><td class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['2'] = {
row1 = '<td class="l dr sb"></td><td class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['5'] = {
row1 = '<td class="l dr db"></td><td class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['f'] = {
row1 = '<td class="l sr nb"></td><td class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['g'] = {
row1 = '<td class="l sr db"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['k'] = {
row1 = '<td class="l dr nb"></td><td class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['s'] = {
row1 = '<td class="l dr db"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
['o'] = {
row1 = '<td class="l nr sb"></td><td class="l db"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['m'] = {
row1 = '<td class="l nr db"></td><td class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['w'] = {
row1 = '<td class="l dr sb"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['z'] = {
row1 = '<td class="l dr db"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['P'] = {
row1 = '<td class="l dr nb"></td><td class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['H'] = {
row1 = '<td class="l dr sb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
['K'] = {
row1 = '<td class="l sr nb"></td><td class="l sb"></td>',
row2 = '<td class="l dr"></td><td class="l"></td>',
},
['N'] = {
row1 = '<td class="l sr sb"></td><td class="l" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['T'] = {
row1 = '<td class="l nr db"></td><td class="l sb"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['Z'] = {
row1 = '<td class="l nr sb"></td><td class="l db"></td>',
row2 = '<td class="l sr"></td><td class="l"></td>',
},
['S'] = {
row1 = '<td class="l sr db"></td><td class="l sb"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['Q'] = {
row1 = '<td class="l sr sb"></td><td class="l db"></td>',
row2 = '<td class="l" colspan="2"></td>',
},
['←'] = {
row1 = '<td class="l sb alt"></td><td class="l sb"></td>',
row2 = '<td class="l alb" colspan="2"></td>',
},
['→'] = {
row1 = '<td class="l sb"></td><td class="l sb art"></td>',
row2 = '<td class="l arb" colspan="2"></td>',
},
['↑'] = {
row1 = '<td class="l sr atl"></td><td class="l atr" rowspan="2"></td>',
row2 = '<td class="l sr"></td>',
},
['↓'] = {
row1 = '<td class="l sr"></td><td class="l abr" rowspan="2"></td>',
row2 = '<td class="l sr abl"></td>',
},
['⇠'] = {
row1 = '<td class="l db alt"></td><td class="l db"></td>',
row2 = '<td class="l alb" colspan="2"></td>',
},
['⇢'] = {
row1 = '<td class="l db"></td><td class="l db art"></td>',
row2 = '<td class="l arb" colspan="2"></td>',
},
['⇡'] = {
row1 = '<td class="l dr atl"></td><td class="l atr" rowspan="2"></td>',
row2 = '<td class="l dr"></td>',
},
['⇣'] = {
row1 = '<td class="l dr"></td><td class="l abr" rowspan="2"></td>',
row2 = '<td class="l dr abl"></td>',
},
['*'] = { -- unlinked crossing
row1 = '<td class="l sb ct"></td><td class="l sb"></td>',
row2 = '<td class="l sr cb"></td><td class="l"></td>',
},
}
-- aliases
connectorCells['0'] = connectorCells['_']
connectorCells['O'] = connectorCells['_']
--------------------------------------------------------------------------------
---Main return object
local p = {}
---Process the arguments to render a HTML `<table>` element.
---@param frame table Interface to the parser (`mw.frame`)
---@return string
p.render = function(frame)
inputArgs = frame:getParent().args -- global input args cache
local boxclass = getArg('boxclass')
local boxstyle = getArg('boxstyle') or ''
-- The unnamed arguments come in rows, e.g.:
-- |A|_|B|#
-- |C|^|D|#
-- Unnamed args = { 'A', '_', 'B', '#', 'C', '^', 'D', '#' }
-- We will iterate over these arguments in rows, which means: Create the table
-- cell HTML for each argument and store it in a buffer. When we reach the
-- end of a row, i.e. a '#' argument, then combine the buffered cells, add
-- them to the processedRows, and clear the buffer for the next row.
---HTML table rows
local processedRows = {}
---Argument index during iteration
local argIndex = 1
---Argument value during iteration
local arg
-- Each row of arguments will actually consist of *two* table rows in
-- the HTML output (one `<tr class="x">`, one `<tr class="y">`). So the buffer
-- consists of two variables, `row1` and `row2`.
---Row buffer during iteration (children of `<tr class="x">`).
local row1 = ''
---Row buffer during iteration (children of `<tr class="y">`).
local row2 = ''
-- Start iterating
while true do
arg = inputArgs[argIndex] -- current unnamed argument
if not arg then
break
end
argIndex = argIndex+1
arg = trim(arg)
-- `arg` is one of these:
-- * a row terminator, then complete the current row and start a new one
-- * a connector (line drawing) or box (content), then create its HTML
-- and insert it into the buffer
-- * a blank string (argument consisting only of whitespace), then ignore it
if arg == '#' then
-- row terminator
processedRows[#processedRows + 1] = processRow(row1, row2)
-- clear the buffer for the next row
row1 = ''
row2 = ''
elseif connectorCells[arg] then
-- connector
row1 = row1 .. connectorCells[arg].row1
row2 = row2 .. connectorCells[arg].row2
elseif arg == '' then
-- blank string, skipped
else
-- content box
local td = mw.html.create('td')
:attr({
class = 'diagram-box',
colspan = 2 * tonumber(getArg(arg .. '_cols') or 3),
rowspan = 2 * tonumber(getArg(arg .. '_rows') or 1),
id = getArg(arg .. '_id'),
})
:addClass(boxclass)
:addClass(getArg(arg .. '_class'))
local style = mergeStyles(boxstyle, arg)
if style then
td:attr('style', style)
end
td:wikitext(trim(inputArgs[arg] or ''))
row1 = row1 .. tostring(td)
end
end
-- We reached the end of the unnamed arguments. If the last argument was not
-- a row terminator, then the buffer still contains the last row, so add that
-- to the output.
if row1 ~= '' then
processedRows[#processedRows + 1] = processRow(row1, row2)
end
-- Insert all the table rows into an HTML `<table>`.
local output = mw.html.create('table')
:attr({
class = 'diagram',
id = getArg('id'),
style = getArg('style') or getArg('css'),
title = getArg('summary'),
})
:addClass(getArg('class'))
:wikitext(table.concat(processedRows)) -- insert the rows
return tostring(output)
end
return p