Модуль:СтММ
Перейти к навигации
Перейти к поиску
Документация
![]() | Этому модулю не хватает документации. |
-- Этот модуль вызывается с помощью шаблонов СтММ и ЛММ
--[=[ Linter:
setmetatable(_G, {
__newindex =
function (_, n)
error("attempt to write to undeclared variable "..n, 2)
end,
__index =
function (_, n)
error("attempt to read undeclared variable "..n, 2)
end,
})
--]=]
local p = {}
local jsontable = mw.loadJsonData('Шаблон:Интерактивная схема Московского метрополитена/data.json')
local function contains(tbl, x)
local t
local found = false
for p, v in pairs(tbl) do
if v == x then
found = p
end
end
return found
end
local function removeparen(text)
return text:gsub( '^%s*(.+)%s+%b()%s*$', '%1' )
end
local function addquotes(text, icon)
if (icon) then
return text
end
return '<span class="stmm-quotes">«</span>' .. text .. '<span class="stmm-quotes">»</span>'
end
local function showicon(code, link)
local iconsize = 15
if (code == 'D4А') then
iconsize = 30
elseif (mw.ustring.find(code, 'D', 1, true)) then
iconsize = 22
end
return '[[File:Moskwa Metro Line ' .. code .. '.svg|' .. iconsize .. 'px|'
.. 'link=' .. link .. '|' .. removeparen(link) .. ']]'
end
local function splitname(text)
if (text) then
local slash = mw.ustring.find(text, '/', 1, true)
if (slash) then
return mw.ustring.sub(text, 1, slash - 1), mw.ustring.sub(text, slash + 1)
end
return text
end
end
local function errors(text, template)
error(text .. '[[Категория:Ошибки в использовании шаблона ' .. (template or 'СтММ') .. ']]' , 0)
end
local function findstation(stationparam)
local csi, newline, newstation, category
local lines = {}
local allanswers = {}
local newjson = {}
local alllines = {}
for _, value in pairs(jsontable.lines) do
newline = {article = value.article, train = value.train, stations = {}}
if (value.number and not value.hidden) then
table.insert(alllines, value.number)
end
for _, value0 in pairs(value.stations or {}) do
if (not value0.hidden) then
newstation = {article = value0.article, line = value.number, rp = removeparen(value0.name or value0.article)}
if (stationparam == newstation.rp or stationparam == value0.oldname) then
if (stationparam == value0.oldname) then
category = '[[Категория:Страницы, требующие переименования станций в шаблоне СтММ]]'
end
table.insert(allanswers, {value0.article, newstation.rp, newstation.line, value.article, value.train, category})
table.insert(lines, newstation.line)
if (value0.csi) then
csi = {value.number, tostring(value0.csi), value.article, #allanswers}
end
end
if (csi and csi[2] == value.number) then
csi[5] = value.article
end
table.insert(newline.stations, newstation)
end
end
if (value.number) then
table.insert(newjson, newline)
end
end
return lines, allanswers, csi, newjson, alllines
end
local function findnextstation(stationparam)
local lines = {}
local allanswers = {}
for _, value in pairs(jsontable) do
for _, value0 in pairs(value.stations or {}) do
if (stationparam == value0.rp) then
table.insert(allanswers, {value0.article, value0.rp, value0.line, value.article, value.train})
table.insert(lines, value0.line)
end
end
end
return lines, allanswers
end
local function findstationhint(stationparam)
local ahint, chint, rp, lowerp
local lowerstation = mw.ustring.gsub(mw.ustring.lower(stationparam), ' +', ' ')
for _, value in pairs(jsontable) do
for _, value0 in pairs(value.stations or {}) do
rp = value0.rp
lowerp = mw.ustring.lower(rp)
if (lowerp == lowerstation) then
return rp
elseif (mw.ustring.find(lowerstation, lowerp, 1, true)
and (not ahint or (mw.ustring.len(rp) > mw.ustring.len(ahint)))) then
ahint = rp
elseif (not ahint and mw.ustring.find(lowerp, lowerstation, 1, true)
and (not chint or (mw.ustring.len(rp) > mw.ustring.len(chint)))) then
chint = rp
end
end
end
return ahint or chint
end
local function formatvariants(vars, cond)
local err = ', возможные варианты: ' .. mw.ustring.gsub(mw.ustring.gsub(mw.text.jsonEncode(vars), '["%[%]]', ''),',', ', ')
if (cond) then
err = err .. '. Можно также использовать параметр «@@» вместо «@» для кроссплатформенных или общих станций'
end
return err
end
local function getargs(frame)
local args = {}
for p, v in pairs(frame:getParent().args) do
args[p] = mw.text.trim(v)
end
return args
end
function p.station(frame)
local startparam = 1
local argsnumber = 0
local iconparam = false
local interchangeparam = false
local hyphenparam = false
local lineparam = ''
local icon = ''
local err = ''
local ts = ''
local args = getargs(frame)
local stationparam, stationname, allanswers, hint, articleans, nameans,
csiparam, csi, unknownpar, lines, hintlines, hintanswers, indexans
for p, _ in ipairs(args) do
argsnumber = math.max(argsnumber, p)
end
if (args[1] == '@') then
iconparam = true
startparam = 2
elseif (args[1] == '-') then
iconparam = true
hyphenparam = true
startparam = 2
elseif (args[1] == '&') then
iconparam = true
interchangeparam = true
startparam = 2
elseif (args[1] == '@@') then
csiparam = args[2]
startparam = 2
end
if (not csiparam and argsnumber - startparam > 1) then
return errors('Слишком много параметров')
end
for p, _ in pairs(args) do
if (not contains({1, 2, 3}, p)) then
if (csiparam) then
unknownpar = true
else
return errors('Неизвестный параметр «' .. p .. '»')
end
end
end
stationparam, stationname = splitname(args[startparam])
if (stationparam == '') then
return errors('Пустое название станции')
end
if (stationname == '') then
return errors('Пустой замещающий текст для отображения вместо названия станции')
end
if (csiparam and (args[startparam + 1] or unknownpar)) then
return errors('Параметр «@@» должен использоваться исключительно с названием станции')
end
if (args[startparam + 1]) then
lineparam = args[startparam + 1]
end
if (not stationparam) then
return errors('Название станции не указано')
end
lines, allanswers, csi, jsontable, alllines = findstation(stationparam)
if (not csi and csiparam) then
return errors('Параметр «@@» должен использоваться только для кроссплатформенных или общих станций')
end
if (#allanswers == 0) then
if (contains(alllines, stationparam) and lineparam ~= '') then
errors('Возможно, вы используете старый синтаксис, станцию следует указывать до линии')
end
hint = findstationhint(stationparam)
if (hint) then
hintlines, hintanswers = findnextstation(hint)
if (#hintanswers <= 1) then
err = '. В номере линии нет необходимости'
elseif (contains(hintlines, lineparam)) then
err = ', она может использовать указанный номер линии: ' .. lineparam
else
err = '. Требуется также номер линии' .. formatvariants(hintlines)
end
err = ', но, возможно, вы имели в виду «' .. hint .. '»' .. err
end
return errors('Станция «' .. mw.ustring.gsub(stationparam, ' +', '<много пробелов>') .. '» неизвестна' .. err)
end
if (mw.text.jsonEncode(args[startparam + 1]) == '""') then
if (#allanswers == 1) then
return errors('Номер линии пуст и не требуется')
elseif (#allanswers > 1) then
return errors('Номер линии пуст' .. formatvariants(lines, csi and iconparam and not hyphenparam))
end
end
if (#allanswers == 1 and lineparam ~= '') then
return errors('Номер линии не требуется: ' .. lineparam)
end
if (not csiparam and ((#allanswers > 1 and not csi) or (#allanswers > 2 and csi)) and lineparam == '') then
return errors('Существует несколько станций с таким названием. Требуется номер линии' .. formatvariants(lines, csi and iconparam and not hyphenparam))
end
if (not csiparam and #allanswers > 1) then
for key, value in pairs (allanswers) do
if (value[3] == lineparam) then
indexans = key
end
end
if (csi and lineparam == '') then
indexans = 1
end
elseif (csi and csiparam) then
indexans = csi[4]
else
indexans = 1
end
if (not indexans) then
return errors('Неверный номер линии: ' .. lineparam .. formatvariants(lines, csi and iconparam and not hyphenparam))
end
articleans = allanswers[indexans][1]
nameans = allanswers[indexans][2]
if (iconparam or csiparam) then
if (hyphenparam) then
icon = ' —'
elseif (csi and lineparam == '') then
icon = icon .. showicon(csi[1], csi[3]) .. showicon(csi[2], csi[5])
else
icon = showicon(allanswers[indexans][3], allanswers[indexans][4])
end
end
if (iconparam) then
ts = frame:extensionTag{
name = 'templatestyles',
args = { src = 'Шаблон:СтММ/styles.css' }
}
end
return '<span style="white-space: nowrap">' .. icon .. ' ' .. addquotes('[[' .. articleans .. '|' .. (stationname or nameans)
.. ']]', not tonumber(mw.ustring.sub(allanswers[indexans][3], 1, 1))
or allanswers[indexans][5] or iconparam or csiparam) .. '</span>' .. ts .. (allanswers[indexans][6] or '')
end
function p.line(frame)
local args = getargs(frame)
local ans = ''
local alllines = {}
local allarticles = {}
local found
for p, v in pairs(args) do
if (type(p) ~= 'number') then
return errors('Неизвестный параметр «' .. p .. '»', 'ЛММ')
end
if (v == '') then
return errors('Пустой параметр № ' .. p, 'ЛММ')
end
end
if (not args[1]) then
return errors('Нет параметров', 'ЛММ')
end
for _, value in ipairs(jsontable.lines) do
if (value.number and not value.hidden) then
table.insert(alllines, value.number)
table.insert(allarticles, value.article)
end
end
for _, value in ipairs(args) do
found = contains(alllines, value)
if (not found) then
return errors('Неизвестная линия «' .. value .. '»', 'ЛММ')
end
ans = ans .. showicon(value, allarticles[found])
end
return '<span style="white-space: nowrap">' .. ans .. ' </span>'
end
local function getprep(frame, text)
return frame:preprocess(text)
end
local function fulldouble(frame)
local cur
local ans = '<table class=wikitable><tr><th colspan=2>@@</th></tr>'
for _, value in pairs(jsontable.lines) do
for _, value0 in pairs(value.stations or {}) do
if (value0.csi) then
cur = '{{СтММ|@@|' .. removeparen(value0.name or value0.article) .. '}}'
ans = ans .. '<tr><td>' .. cur .. '</td><td>' .. frame:preprocess(cur) .. '</td></tr>'
--ans = ans .. '\n* ' .. removeparen(value0.article) .. ', ' .. value.number .. ', ' .. value0.csi
end
end
end
ans = ans .. '</table>'
return ans
end
function p.full(frame)
if (frame.args[1] == '0') then
return fulldouble(frame)
end
local ans = '<table class=wikitable>'
local rp
local value
local left, right, text
value = jsontable.lines[tonumber(frame.args[1])]
if (value.number and not value.hidden) then
ans = ans .. '<tr><th>' .. value.number .. '</th><th>' .. (value.name or value.article) .. '</th></tr>'
for _, value0 in pairs(value.stations or {}) do
rp = removeparen(value0.name or value0.article)
_, left = pcall(getprep, frame, '{{СтММ|@|' .. rp .. '}}')
_, right = pcall(getprep, frame, '{{СтММ|@|' .. rp .. '|' .. value.number .. '}}')
if (not mw.ustring.find(left, 'strong')) then
ans = ans .. '<tr><td>{{СтММ|@|' .. rp .. '}}</td><td>' .. left .. '</td></tr>'
end
if (not mw.ustring.find(right, 'strong')) then
ans = ans .. '<tr><td>{{СтММ|@|' .. rp .. '|' .. value.number .. '}}</td><td>' .. right .. '</td></tr>'
end
end
end
ans = ans .. '</table>'
return ans
end
--[==[ Схема шаблона Московские маршруты
?param-text: сплиний(param-1)
else: ?[[Файл:Logo train transilien.svg|15px|link=param-r/23|бсвл]]
is-station(param-1): спстанций(param-1)
else: [[Файл:Moskwa Metro Line param-1 (line?inv:alt)(искл).svg|15px|link=param-l1..сплиний(param-1)|бсвл]]
?param-line and ~= 0:
<span цвет=param-style..(param-1{12357}?white:black>[[сплиний(param-1)|param-2..сплиний(param-1)]]</span>
else: ?[[Файл:Moskwa Metro Line param-2/34 alt.svg|15px|link=param-l2/34..сплиний(param-2/34)|бсвл]]
?[[param-c (станция МЦК)|param-c]]
?[[param-m (станция монорельса)|param-m]]
?[[param-s (станция метро?(, param-d)(искл))|param-s]]
?[[Файл:Logo train transilien.svg|15px|link=param-r/23|бсвл]]
[[Файл:Moskwa Metro Line param-1 alt.svg|15px|link=param-l1..сплиний(param-1)|бсвл]]
?[[Файл:Moskwa Metro Line param-2/34 alt.svg|15px|link=param-l2/34..сплиний(param-2/34)|бсвл]]
?[[param-l1|param-cn]]
?[[param-c (станция МЦК)|param-c]]
?[[param-m (станция монорельса)|param-m]]
?nodisambig([[param-s (станция метро?(, param-d)(искл))|param-s]])
?param-sn
]==]
return p