Модуль:Песочница/CupIvan/треклист/песочница
Перейти к навигации
Перейти к поиску
Документация
local time = require('Модуль:Песочница/CupIvan/время/песочница')
local css = 'Модуль:Песочница/CupIvan/треклист/style.css' -- FIXME: перенести в основной файл
local p = {}
-- генерация HTML разметки треклиста
function make_html(t)
if not t.width then t.width = '100%' end
if not t.columns then t.columns = {number = 1, title = 1, length = 1} end
-- названия колонок
if not t.title then t.title = 'Название' end
if not t.author then t.author = 'Автор' end
if not t.lyrics then t.lyrics = 'Слова' end
if not t.music then t.music = 'Музыка' end
if not t.extra then t.extra = '' end
if not t.length then t.length = 'Длительность' end
local html = mw.html.create('table')
html:addClass('wikitable ts-Tracklist')
if t.collapsed then html:addClass('mw-collapsible mw-collapsed') end
html:css('width', t.width)
if t.headline then
html:tag('caption'):wikitext(t.headline)
end
local numExtraColumns = 0
for k, v in pairs({ 'author', 'lyrics', 'music', 'extra'})
do if t.columns[v] then numExtraColumns = numExtraColumns + 1 end end
local w = { title='100%', other=0 }
if numExtraColumns == 1 then w = { title='60%', other='40%' } end
if numExtraColumns == 2 then w = { title='40%', other='30%' } end
if numExtraColumns == 3 then w = { title='30%', other='20%' } end
if numExtraColumns == 4 then w = { title='30%', other='15%' } end
local tr = html:tag('tr')
if t.columns.number then tr:tag('th'):attr('scope', 'col'):addClass('number') :wikitext('№'); end
if t.columns.title then tr:tag('th'):attr('scope', 'col'):wikitext(t.title); end
if t.columns.author then tr:tag('th'):attr('scope', 'col'):css('width', w.other):wikitext(t.author); end
if t.columns.lyrics then tr:tag('th'):attr('scope', 'col'):css('width', w.other):wikitext(t.lyrics); end
if t.columns.music then tr:tag('th'):attr('scope', 'col'):css('width', w.other):wikitext(t.music); end
if t.columns.extra then tr:tag('th'):attr('scope', 'col'):css('width', w.other):wikitext(t.extra); end
if t.columns.length then tr:tag('th'):attr('scope', 'col'):addClass('length') :wikitext(t.length); end
local numColumns = table.getn(tr.nodes)
local total_length = 0
for n, a in pairs(t.tracks)
do
if t.side == nil or not t.side or t.side == a.side then
local title = ''
if a.title then
if a.title == '' then title = "''Без названия''" else title = '«'..a.title..'»' end
end
if a.note then title = title .. ' <small>('..a.note..')</small>' end
local tr = html:tag('tr')
if t.columns.number then tr:tag('td'):wikitext(a.number..'.'):addClass('number') end
if t.columns.title then tr:tag('td'):wikitext(title) end
if t.columns.author then tr:tag('td'):wikitext(a.author) end
if t.columns.lyrics then tr:tag('td'):wikitext(a.lyrics) end
if t.columns.music then tr:tag('td'):wikitext(a.music) end
if t.columns.extra then tr:tag('td'):wikitext(a.extra) end
if t.columns.length then tr:tag('td'):wikitext(time.formatToString(a.length, "short")):addClass('length') end
if a.length then total_length = total_length + a.length end
end
end
if t.columns.length then
if t.total_length ~= nil then total_length = time.stringToSeconds(t.total_length) end
html:tag('tr'):tag('td'):attr('colspan', numColumns)
:addClass('total'):wikitext(time.formatToString(total_length, "long"))
end
local st = ''
st = st .. mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = 'Шаблон:Tracklist/styles.css'}}
st = st .. mw.getCurrentFrame():extensionTag{ name = 'templatestyles', args = { src = css }} -- FIXME: перенести в основной файл
if t.all_writing then st = st .. 'Слова и музыка всех песен ' .. t.all_writing .. '. ' end
if t.all_lyrics then st = st .. 'Все тексты написаны ' .. t.all_lyrics .. '. ' end
if t.all_music then st = st .. 'Вся музыка написана ' .. t.all_music .. '. ' end
st = st .. tostring(html)
return st
end
-- загрузка данных из шаблона
function p.tracks(frame)
local t, columns = {}, {}
t = frame.args; t.tracks={}; t.columns={}
if not t.start then t.start = 1 end
t.columns.number = 1 -- показываем колонку с номером
-- формируем таблицу с данными
local i = 1
local lineNumber, columnNumber = 0, 0
while frame.args[i] ~= nil
do
local value = mw.text.trim(frame.args[i])
if frame.args[i] == "" then lineNumber = lineNumber + 1; columnNumber = 1 end
if lineNumber == 1
then
columns[columnNumber] = value
t.columns[value] = 1
else
if t.tracks[lineNumber] == nil then t.tracks[lineNumber] = {number = lineNumber-1+t.start-1} end
if columns[columnNumber] == 'length' then value = time.stringToSeconds(value) end
t.tracks[lineNumber][columns[columnNumber]] = value
end
columnNumber = columnNumber + 1
i = i + 1
end
-- данные в старом формате (обратная совместимость)
local i = 1
while (frame.args['title'..i] ~= nil) or (i < 30)
do
local x = 'title'
if frame.args[x..i] ~= nil then
t.tracks[i] = {number = tonumber(i), title = frame.args[x..i]}; t.columns[x] = 1
x = 'note'; if frame.args[x..i] ~= nil then t.columns[x] = 1; t.tracks[i][x] = frame.args[x..i] end
x = 'writer'; if frame.args[x..i] ~= nil then t.columns[x] = 1; t.tracks[i][x] = frame.args[x..i] end
x = 'lyrics'; if frame.args[x..i] ~= nil then t.columns[x] = 1; t.tracks[i][x] = frame.args[x..i] end
x = 'music'; if frame.args[x..i] ~= nil then t.columns[x] = 1; t.tracks[i][x] = frame.args[x..i] end
x = 'extra'; if frame.args[x..i] ~= nil then t.columns[x] = 1; t.tracks[i][x] = frame.args[x..i] end
x = 'length'; if frame.args[x..i] ~= nil then t.columns[x] = 1; t.tracks[i][x] = time.stringToSeconds(frame.args[x..i]) end
end
i = i + 1
end
return make_html(t)
end
-- загрузка данных из wikidata
function p.wikidata(frame)
local from = frame.args.from
local st = ''
local entity = mw.wikibase.getEntity(from)
local tracks = entity['claims']['P658']
local t = {tracks={}, columns={ title=1 }}
local numSides = 1
-- если задано количество - генерируем полный список треков
local numParts = entity['claims']['P2635']
if numParts then
for k, a in pairs(numParts)
do
if a['mainsnak']['datavalue']['value']['unit'] == 'http://www.wikidata.org/entity/Q7302866'
then
local N = tonumber(a['mainsnak']['datavalue']['value']['amount'])
for i=1,N do t.tracks[i]={ number=i } end
end
end
end
for k1, a1 in pairs(tracks)
do
local track = {}
track['title'] = entityTitle(a1['mainsnak']['datavalue']['value']['id'])
number = k1
setDefaultPerson(t, track, 'lyrics', a1, 'P676')
setDefaultPerson(t, track, 'music', a1, 'P86')
setDefaultPerson(t, track, 'author', a1, 'P50')
for k2, a2 in pairs(a1['qualifiers'])
do
if k2 == 'P518' then -- сторона диска
if a2[1]['datavalue']['value']['id'] == 'Q3827523' then track['side'] = 1 end
if a2[1]['datavalue']['value']['id'] == 'Q13432985' then track['side'] = 2; numSides = 2 end
end
if k2 == 'P1545' then -- номер трека
track['number'] = tonumber(a2[1]['datavalue']['value'])
t.columns.number = 1
number = tonumber(track['number'])
end
if k2 == 'P2047' then -- длительность
local seconds = tonumber(a2[1]['datavalue']['value']['amount'])
track['length'] = seconds
t.columns.length = 1
end
if k2 == 'P175' then -- исполнитель
track['extra'] = _peoples(a2)
t.columns.extra = 1
t.extra = 'Исполнитель'
end
if k2 == 'P676' then -- автор слов
track['lyrics'] = _peoples(a2)
t.columns.lyrics = 1
end
if k2 == 'P86' then -- композитор
track['music'] = _peoples(a2)
t.columns.music = 1
end
if k2 == 'P50' then -- автор
track['author'] = _peoples(a2)
t.columns.author = 1
end
end
t.tracks[number] = track
end
if numSides == 1 then return make_html(t) end
local st = ''
for i = 1, numSides do
t.headline = 'Сторона ' .. i
t.side = i
st = st .. make_html(t)
end
return st
end
-- список авторов произведения
function _peoples(a)
local st = ''
for k, v in pairs(a)
do
if st ~= '' then st = st .. ', ' end
st = st .. entityPersonName(v['datavalue']['value']['id'])
end
return st
end
-- фамилия и имя человека
function entityPersonName(Q)
local entity = mw.wikibase.getEntity(Q)
local shortName = _property(entity, 'P1813')
if shortName == '' then shortName = _property(entity, 'P735')..' '.._property(entity, 'P734') end
local name = entityUrl(Q)
if shortName ~= '' then
if name == '' then name = shortName else name = name..'|'..shortName end
end
return '[['..name..']]'
end
-- URL записи в wikipedia
function entityUrl(Q)
local entity = mw.wikibase.getEntity(Q)
if not entity then return '' end
if entity['sitelinks']['ruwiki'] ~= nil then return ':ru:'..entity['sitelinks']['ruwiki']['title'] end
if entity['sitelinks']['enwiki'] ~= nil then return ':en:'..entity['sitelinks']['enwiki']['title'] end
return ''
end
-- заголовок записи
function entityTitle(Q)
local entity = mw.wikibase.getEntity(Q)
if not entity then return '' end
if entity['labels']['ru'] ~= nil then return entity['labels']['ru']['value'] end
if entity['labels']['en'] ~= nil then return entity['labels']['en']['value'] end
end
function _property(a, P)
local claim = a.claims[P]
if not claim then return '' end
local v = claim[1]['mainsnak']['datavalue']['value']
if v.text then return v.text end
return entityTitle(v.id)
end
function setDefaultPerson(t, track, field, a, P)
local entity = mw.wikibase.getEntity(a['mainsnak']['datavalue']['value']['id'])
local claim = entity.claims[P]
if not claim then return end
local Q = claim[1]['mainsnak']['datavalue']['value']['id']
track[field] = entityPersonName(Q)
t.columns[field] = 1
end
return p