Модуль:Tables
AutoNumBox — функция для шаблона НумерацияТаблицы
Документацию см. на странице {{НумерацияТаблицы}}
AutoNumSort — функция для шаблона Автонумерация
Документацию см. на странице {{Автонумерация}}
DataOutput — функция для шаблона ВыводДанных
Документацию см. на странице {{ВыводДанных}}
DataOutput2 — функция для шаблона ВыводДанных2
Документацию см. на странице {{ВыводДанных2}}
local p = {}
-- **********************************************************
-- Вызов через шаблон {{НумерацияТаблицы}}
-- Заменяет число в первой ячейке на номер строки
function p.AutoNumBox2(frame)
local g = frame:getParent().args[1]
local NumStr = tonumber (frame:getParent().args['Старт'] or "1");
if g == nil then return "Нет данных" end
g = g:gsub(".*{|(.*)|}.*", "%1")
local Titul = g:sub(1, (g:find ("\n!") or 1) - 1)
g = g:sub((g:find ("\n!") or 1))
g = g:gsub("||", "\n|")
local Pos0 = 0
while g:find("|%-[^|]*(|[^\n]*\n)", Pos0 + 1) ~= nil do
Pos1, Pos2 = g:find("|%-[^|]*(|[^\n]*\n)", Pos0 + 1)
while g:find("|", Pos1 + 1) ~= nil and g:find("|", Pos1 + 1) < Pos2 do
Pos1 = g:find("|", Pos1 + 1)
end
if g:find("%d", Pos1) ~= nil and g:find("%d", Pos1) < Pos2 then
Pos3, Pos4 = g:find("%d+", Pos1)
g = g:sub(1, Pos3 - 1)..NumStr..g:sub(Pos4 + 1)
NumStr = NumStr + 1
end
Pos0 = Pos2
end
return "{|"..Titul..g.."|}"
end
-- **********************************************************
-- Вызов напрямую
-- Заменяет символ # в первой ячейке на номер строки
function p.AutoNumBox ( frame )
local NumStr = tonumber (frame.args['Старт'] or "1");
local g = frame.args[1]
g = g:gsub("^%s- -{{", "", 1)
g = g:gsub("}}%s- -$", "", 1)
pattern = "|%s*#%s*%s*|"
while string.find (g, pattern) ~= nil do
g = g:gsub(pattern, "|"..NumStr.."\n".."|", 1)
NumStr = NumStr + 1
end
return g
end
-- **********************************************************
function p.AutoNum ( frame )
local args = frame.args;
local Style = (frame.args['Оформление'] or "standard");
local Column = tonumber (frame.args['Столбцов'] or "0");
local NumStr = tonumber (frame.args['Старт'] or "1");
local Title0 = (frame.args['Заголовок0'] or "№")
local Titles = {}
for i = 1, Column do
Titles[i] =(frame.args["Заголовок"..i] or "Заголовок"..i)
end
local Width0 = (frame.args['Ширина0']);
local Widths = {}
for i = 1, Column do
Widths[i] =(frame.args["Ширина"..i])
end
local Align0 = (frame.args['Выравнивание0'] or "center")
local Aligns = {}
for i = 1, Column do
Aligns[i] =(frame.args["Выравнивание"..i] or "left")
end
local g="<table class = '"..Style.."'>"
-- Строка заголовков
g = g.."<tr>"
---- Заголовок столба с номерами строк
g = g.."<th scope='col'"; if Width0 ~= nil then g = g.." width='"..Width0.."'" end; g = g..">"
g = g..Title0.."</th>"
---- Остальные заголовки
for i = 1, Column do
g = g.."<th scope='col'"; if Widths[i] ~= nil then g = g.." width='"..Widths[i].."'" end; g = g..">"
g = g..Titles[i].."</th>"
end
g = g.."</tr>"
-- Строки данных
J = 1
while args[(J-1)*Column+1] ~= nil do
g = g.."<tr><td style='text-align:"..Align0.."'>"..NumStr.."</td>"
for i = 1, Column do
if args[(J-1)*Column+i] == nil then
g = g.."<td></td>"
else
g = g.."<td style='text-align:"..Aligns[i].."'>"..args[(J-1)*Column+i].."</td>"
end
end
g = g.."</tr>"
NumStr = NumStr + 1
J = J + 1
end
g = g.."</table>"
return g
end
-- **********************************************************
function p.AutoNumSort(frame)
local args = frame:getParent().args
local Column = tonumber(args['Столбцов'] or "0")
if Column == 0 then return "Невозможно определить количество столбцов" end
local TempSort = (args['Сортировка'] or "0")
local SortColumn = tonumber(string.match(TempSort, "%d*")) or 0
if SortColumn > Column then SortColumn = 0 end
local SortAsNumber = string.match(TempSort, "#") ~= nil
local SortDescend
if SortAsNumber
then SortDescend = string.find(TempSort, "<") == nil
else SortDescend = string.find(TempSort, ">") ~= nil end
local Strings={}
local NumCell = 0
while args[NumCell + 1] ~= nil or NumCell%Column ~= 0 do
NumCell = NumCell + 1
if (args[NumCell] == nil) then args[NumCell]="" end
-- NumCell%Column==0 значит строка сформирована
if NumCell%Column == 0 then
local TempString = {NumCell-Column+1}
if SortAsNumber then
KeyCell=args[TempString[1]+SortColumn-1]
KeyCell=mw.ustring.gsub(KeyCell, ".*<span[^>]*style=[^>]*display: none;[^>]*>([^<]*)</span>.*", "%1")
KeyCell=mw.ustring.gsub(KeyCell, "<span[^>]*>[^<]*</span>", "")
KeyCell=mw.ustring.gsub(KeyCell, ",",".")
KeyCell=mw.ustring.gsub(KeyCell, " ","")
KeyCell=mw.ustring.gsub(KeyCell, " ","")
KeyCell=mw.ustring.gsub(KeyCell, "%s","")
KeyCell=mw.ustring.match(KeyCell, "^[^0-9-]*(-?%d+%.?%d*)") or ""
TempString.Key=tonumber(KeyCell)
elseif SortColumn > 1 then
TempString.Key = (args[TempString[1]+SortColumn-1] or "")
-- Возможность сортировки по скрытому ключу, например через шаблон {{~}}
TempString.Key = mw.ustring.gsub(TempString.Key, '<span[^>]+>', "")
-- Сортировка ё как е
TempString.Key = mw.ustring.gsub(TempString.Key, "ё", "е")
TempString.Key = mw.ustring.gsub(TempString.Key, "Ё", "Е")
-- trim
TempString.Key = mw.ustring.gsub(TempString.Key, "^%s*(.-)%s*$", "%1")
else TempString.Key = tonumber(TempString[1]) end
TempString.Group = mw.ustring.gsub(mw.ustring.gsub(args[TempString[1]], "#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]", ""),"[^a-zA-Zа-яА-Я0-9]","")
table.insert(Strings, TempString)
end
end
local function SortString(a, b)
if a.Group ~= b.Group then return a.Group < b.Group end
if SortDescend then a, b = b, a end
if SortAsNumber or (SortColumn < 2) then
return a.Key < b.Key
else
local LenA = mw.ustring.len(a.Key)
local LenB = mw.ustring.len(b.Key)
for i = 1, (LenA < LenB) and LenA or LenB do
if mw.ustring.codepoint(a.Key, i, i) ~= mw.ustring.codepoint(b.Key, i, i) then
return mw.ustring.codepoint(a.Key, i, i) < mw.ustring.codepoint(b.Key, i, i)
end
end
return LenA < LenB
end
end
-- Сортировка строк по группам и ключу
table.sort(Strings, SortString)
-- Формироание HTML-таблицы
local HTML = mw.html.create('table')
HTML:attr('class', (args['Оформление'] or "standard"))
if args['Ручное оформление']~=('' or nil) then
HTML:attr('style', args['Ручное оформление'])
end
-- Название таблицы
if args['Название'] then
TempCaption=HTML:tag('caption')
:wikitext(args['Название'])
:css('text-align', 'left')
:css('white-space', 'nowrap')
end
-- Строка заголовков
local TempRow
TempRow = HTML:tag('tr')
TempHeader=TempRow:tag('th'):attr('scope', 'col')
if args["Ширина1"] then TempHeader:css('width', (args["Ширина1"])) end
TempHeader:wikitext(args['Заголовок1'] or "№")
for i = 2, Column do
TempColumn=TempRow:tag('th'):attr('scope', 'col')
if args["Ширина"..i] then TempColumn:css('width', (args["Ширина"..i])) end
TempColumn:wikitext(args["Заголовок"..i] or "Заголовок"..i)
if args["Сортировка"..i]=="без сортировки" then
TempColumn:addClass('unsortable')
elseif args["Сортировка"..i]=="число" then
TempColumn:attr('data-sort-type', 'number')
elseif args["Сортировка"..i]=="дата" then
TempColumn:attr('data-sort-type', 'date')
end
end
-- Строки данных
local HideNum = 0
local NumStr = tonumber (args['Старт'] or "1") - 1
local Backlight = (args['Подсветка'] or "class='bright'"):gsub("\"", "'")
for Index, TempString in pairs(Strings) do
TempRow = HTML:tag('tr')
local first = args[TempString[1]]
-- Стиль оформления строк
if string.find(first, "%$") ~= nil then TempRow:attr('class', 'shadow')
elseif string.find(first, "%%") ~= nil then TempRow:attr('class', 'bright')
elseif string.find(first, "@") ~= nil then TempRow:attr('class', 'dark')
elseif string.find(first, "%+") ~= nil then
for Part in string.gmatch(Backlight, "[%w]*=%s*'[^']*'") do
TempRow:attr(string.match(Part, "([^=]*)="), string.match(Part, "'([^']*)'"))
end
elseif string.find(first, "#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]") ~= nil then TempRow:css('background-color', string.match(first, '#[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'))
end
if string.find(first, "!") ~= nil then TempRow:css('font-weight','bold') end
-- Вывод номера строки
if string.find(first, "-") ~= nil then
HideNum = HideNum + 0.000001
TempRow:tag('td')
:tag('span')
:attr('style', 'display: none; speak: none;')
:wikitext( tonumber(NumStr + HideNum))
else
NumStr = NumStr + 1
TempRow:tag('td')
:css('text-align', (args['Выравнивание1'] or "center") )
:wikitext(tonumber(NumStr))
end
-- Вывод ячеек строки
for i = 2, Column do
TempTd=TempRow:tag('td')
KeyCell=""
if args["Сортировка"..i]=="число" then
KeyCell=args[TempString[1]+i-1]
KeyCell=mw.ustring.gsub(KeyCell, ".*<span[^>]*style=[^>]*display: none;[^>]*>([^<]*)</span>.*", "%1")
KeyCell=mw.ustring.gsub(KeyCell, "<span[^>]*>[^<]*</span>", "")
KeyCell=mw.ustring.gsub(KeyCell, ",",".")
KeyCell=mw.ustring.gsub(KeyCell, " ","")
KeyCell=mw.ustring.gsub(KeyCell, " ","")
KeyCell=mw.ustring.gsub(KeyCell, "%s","")
KeyCell=mw.ustring.match(KeyCell, "^[^0-9-]*(-?%d+%.?%d*)") or ""
TempTd:attr('data-sort-value', KeyCell)
end
TempTd:wikitext( mw.text.trim( args[TempString[1] + i - 1] ) )
if args["Выравнивание"..i] and args["Выравнивание"..i] ~= "left" then
TempTd:css('text-align', args["Выравнивание"..i])
end
end
end
return tostring(HTML)
end
-- **********************************************************
function p.DataOutput(frame)
local args = frame:getParent().args
local Tab = args.tab
local NumColumns = tonumber(args['Столбцов']) or 9;
local Titul = args['Заголовок'] or "";
local Reverse = args['Реверс'] ~= nil
local Style = args['Оформление'] or "standard";
local function FormatF(Number)
local lang = mw.language.getContentLanguage()
return lang:formatNum(tonumber(Number))
end
local function FormatT(NewRecord, OldRecord)
if OldRecord == nil then
return ""
elseif NewRecord > OldRecord then
if Reverse then
return "<span style='color: red; font-weight:bold; font-size: larger;'>↗</span>"
else
return "<span style='color: #0c0; font-weight:bold; font-size: larger;'>↗</span>"
end
elseif NewRecord < OldRecord then
if Reverse then
return "<span style='color: #0c0; font-weight:bold; font-size: larger;'>↘</span>"
else
return "<span style='color: red; font-weight:bold; font-size: larger;'>↘</span>"
end
else
return "<span style='color:#0AF; font-weight:bold;'>→</span>"
end
end
local k, v
local NumData = 0
for k, v in pairs( args ) do
if type(k) ~= 'string' then
NumData = NumData + 1
end
end -- for k, v
NumData = NumData / 2
if NumData < NumColumns then
NumColumns = NumData
end
-- Формирование HTML-таблицы
local HTML = mw.html.create('table')
HTML:attr('class', Style)
local TempRow
local NumRecord
local OldRecord
local NewRecord
if Titul then
TempRow = HTML:tag('th'):attr('scope', 'colgroup'):attr('colspan', NumColumns):wikitext(Titul)
end
for i = 1, math.ceil(NumData / NumColumns) do
TempRow = HTML:tag('tr'):addClass("bright")
for j = 1, NumColumns do
NumRecord = ((i - 1) * NumColumns + j) * 2 - 1
if args[NumRecord] == nil then
TempRow:tag('th'):attr('scope', 'col'):wikitext("")
else
TempRow:tag('th'):attr('scope', 'col'):wikitext(args[NumRecord])
end
end
TempRow = HTML:tag('tr'):css('text-align', 'center')
for j = 1, NumColumns do
NumRecord = ((i - 1) * NumColumns + j ) * 2
if type(tonumber(args[NumRecord])) ~= "number" then
TempRow:tag('td'):wikitext(args[NumRecord])
OldRecord = nil
else
NewRecord = tonumber(args[NumRecord])
TempRow:tag('td'):wikitext(FormatT(NewRecord, OldRecord) .. FormatF(NewRecord))
OldRecord = NewRecord
end
end
end
return tostring(HTML)
end
-- **********************************************************
function p.DataOutput2(frame)
local args = frame:getParent().args
local NumColumns
if type(tonumber(args['Столбцов'])) == "number" then
NumColumns = tonumber(args['Столбцов'])
else
NumColumns = 9
end
local Titul = args['Заголовок'] or '';
local Format = args['Формат'] or 'Таблица';
local Reverse = args['Реверс'] ~= nil
local Style = args['Оформление'] or 'standard';
local function FormatF(Number)
local lang = mw.language.getContentLanguage()
return lang:formatNum(tonumber(Number))
end
local function FormatT(NewRecord, OldRecord)
if OldRecord == nil then
return ""
elseif NewRecord > OldRecord then
if Reverse then
return "<span style='color: red; font-weight:bold; font-size: larger;'>↗</span>"
else
return "<span style='color: #0c0; font-weight:bold; font-size: larger;'>↗</span>"
end
elseif NewRecord < OldRecord then
if Reverse then
return "<span style='color: #0c0; font-weight:bold; font-size: larger;'>↘</span>"
else
return "<span style='color: red; font-weight:bold; font-size: larger;'>↘</span>"
end
else
return "<span style='color:#0AF; font-weight:bold;'>→</span>"
end
end
local NumData = 0
while args[(NumData + 1) * 3 - 2] ~= nil do
NumData = NumData + 1
end
if NumData < NumColumns then
NumColumns = NumData
end
if Format == 'г' or Format == 'Год' then
return args[NumData * 3 - 2]
elseif Format == 'ч' or Format == 'Безформат' or Format == 'Число' then
return args[NumData * 3 - 1]
elseif Format == 'с' or Format == 'Ссылка' then
return args[NumData * 3]
elseif Format == 'ф' or Format == 'Формат' then
return FormatF(args[NumData * 3 -1])
elseif Format == 'фс' or Format == 'ФорматСсылка' then
return FormatF(args[NumData * 3 -1]) .. args[NumData * 3]
elseif Format == 'фсг' or Format == 'ФорматСсылкаГод' then
return FormatF(args[NumData * 3 -1]) .. args[NumData * 3] .. ' (' .. args[NumData * 3 - 2] .. ')'
elseif Format == 'т' or Format == 'Тренд' then
return FormatT(args[NumData * 3 - 1], args[NumData * 3 - 4]) .. FormatF(args[NumData * 3 - 1])
elseif Format == 'тс' or Format == 'Значение' or Format == 'ТрендСсылка' then
return FormatT(args[NumData * 3 - 1], args[NumData * 3 - 4]) .. FormatF(args[NumData * 3 - 1]) .. args[NumData * 3]
elseif Format == 'тсг' or Format == 'ТрендСсылкаГод' then
return FormatT(args[NumData * 3 - 1], args[NumData * 3 - 4]) .. FormatF(args[NumData * 3 - 1]) .. args[NumData * 3] .. ' (' .. args[NumData * 3 - 2] .. ')'
else
-- Формирование HTML-таблицы
local HTML = mw.html.create('table')
HTML:attr('class', Style)
local TempRow
local NumRecord
local OldRecord
local NewRecord
if Titul then
TempRow = HTML:tag('th'):attr('scope', 'colgroup'):attr('colspan', NumColumns):wikitext(Titul)
end
for i = 1, math.ceil(NumData / NumColumns) do
TempRow = HTML:tag('tr'):addClass("bright")
for j = 1, NumColumns do
NumRecord = ((i - 1) * NumColumns + j) * 3 - 2
if args[NumRecord] == nil then
TempRow:tag('th'):attr('scope', 'col'):wikitext("")
else
TempRow:tag('th'):attr('scope', 'col'):wikitext(args[NumRecord]..(args[NumRecord+2] or ""))
end
end
TempRow = HTML:tag('tr'):css('text-align', 'center')
for j = 1, NumColumns do
NumRecord = ((i - 1) * NumColumns + j ) * 3 - 1
if type(tonumber(args[NumRecord])) ~= "number" then
TempRow:tag('td'):wikitext(args[NumRecord])
OldRecord = nil
else
NewRecord = tonumber(args[NumRecord])
TempRow:tag('td'):wikitext(FormatT(NewRecord, OldRecord) .. FormatF(NewRecord))
OldRecord = NewRecord
end
end
end
return tostring(HTML)
end
end
return p