Модуль:Tables
Версия от 23:15, 2 января 2022; imported>Putnik (порежем пробелы по краям)
Для документации этого модуля может быть создана страница Модуль:Tables/doc
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[^>]+>","") 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, "^%D*(%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(args[TempString[1]], "[^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('th') :wikitext(args['Название']) :attr('colspan', Column) :attr('scope', 'colgroup') 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 end if string.find(first, "!") ~= nil then TempRow:attr('style', '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=mw.ustring.gsub(args[TempString[1]+i-1], ",",".") KeyCell=mw.ustring.gsub(KeyCell, " ","") KeyCell=mw.ustring.gsub(KeyCell, "<span[^>]+>","") KeyCell=mw.ustring.gsub(KeyCell, "%s","") KeyCell=mw.ustring.match(KeyCell, "^%D*(%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