このモジュールについての説明文ページを モジュール:Tracklist/doc に作成できます
local p = {} --共通変数 local track = {} --トラックテーブル格納用テーブル local all = {} --全○○格納用テーブル local desc = {nil, nil} --コメント格納用テーブル local credits = {} --クレジット表示可否格納用テーブル local args = {} --その他引数格納用テーブル local col = 0 --列数 local width = {} --列幅格納用テーブル local collapsed = false --折りたたみ可否 local writer, lyrics, music, arranger, strings_arrange, brass_arrange, horn_arrange, orchestra_arrange, remix, singer, extra, length = function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end, function() return '' end --基本セル関数 local md = true --microdata on/off --[[ 引数取得 ]] local function getArgs(frame) local t_info, t_num = '', 0 local func_credits = function(v) if v == 'yes' then return true end local alias = {'+arrangements', '+a', '+編曲', '・編曲'} for _k, _v in ipairs(alias) do if v == _v then return _v end end return false end for k, v in pairs(require('Module:Arguments').getArgs(frame, {parentOnly = true})) do if string.match(k, '^%D+%d+$') then --各トラック格納 t_info, t_num = string.match(k, '(%D+)(%d+)') if not track[t_num] then track[t_num] = {} end track[t_num][1] = tonumber(t_num) -- トラック番号はkey=1で記録 track[t_num][t_info] = v -- トラック情報はkey=引数で記録 elseif string.match(k, 'all_') then --全○○格納 local pattern = string.gsub(k, 'all_', '') if not all[pattern] then all[pattern] = {nil, v} end elseif string.match(k, '^%d$') then --コメント格納 desc[k] = string.gsub(v, '^([*#;:])', '\n%1') elseif string.match(k, '_credits') then --クレジット表示可否格納 credits[string.gsub(k, '_credits', '')] = func_credits(v) else -- その他格納 args[k] = v end end --allの整理 if all then local function isSame(a, b) --リンクを考慮して文字列を比較する if a and b then return (string.match(a[2], '%[%[.-%|(.-)]]') or string.match(a[2], '%[%[(.-)]]') or a[2]) == (string.match(b[2], '%[%[.-%|(.-)]]') or string.match(b[2], '%[%[(.-)]]') or b[2]) else return false end end if not all.writing and isSame(all.lyrics, all.music) then all.writing = {nil, all.lyrics[2]} end if all.writing then all.lyrics, all.music = nil, nil all.writing[1] = '全作詞・作曲: ' else if all.lyrics then all.lyrics[1] = '全作詞: ' end if all.music then all.music[1] = '全作曲: ' end end if isSame(all.writing, all.arrangements) then all.all = {'全作詞・作曲・編曲: ', all.writing[2]} all.writing, all.arrangements = nil, nil else if all.arrangements then all.arrangements[1] = '全編曲: ' end end if isSame(all.music, all.arrangements) then all.producing = {'全作曲・編曲: ', all.music[2]} all.music, all.arrangements = nil, nil end end credits.extra = args.extra_column if credits.writing then credits.lyrics, credits.music = false, false if credits.writing ~= true then credits.arrangements = false end end if credits.music and credits.music ~= true then credits.arrangements = false end collapsed = (args.collapsed == 'yes') md = (args.microdata == 'no') and false or args.id end --[[ 列数計算 ]] local function calc_columns() local col = 2 --#,タイトル for k, v in pairs(track) do if not v.length then credits.length = false else credits.length = true break end end for k, v in pairs(credits) do if v then col = col + 1 end end return col end --[[ 幅計算 ]] local function calc_width() local width = {} if not credits.length then col = col + 1 end if col < 4 then width.title, width.credits = '100%', 'auto' elseif col < 5 then width.title, width.credits = '60%', '40%' elseif col < 6 then width.title, width.credits = '40%', '30%' elseif col < 7 then width.title, width.credits = '40%', '20%' else width.title, width.credits = '40%', '15%' end return width end --[[ ヘッダ部 ]] local function header() --キャプション定義 local result = (args.headline or collapsed) and '<caption style="text-align:left; padding:0.25em 0.9em; font-weight:bold; line-height:1.4em; white-space:nowrap;">' .. (args.headline or 'トラックリスト') .. '</caption>' or '' if collapsed then --折りたたみ表示において[表示]ボタン行追加 result = result .. '<tr style="position:absolute; top:0.25em; right:0.9em; speak:none;"><th colspan="' .. col .. '"></th></tr>' end local newall = {} --全○○表示用テーブル if all then --全○○/コメント表示のとき if all.lyrics and not credits.lyrics then newall[1] = all.lyrics[1] .. all.lyrics[2] end if all.music and not credits.music then newall[#newall + 1] = all.music[1] .. all.music[2] end if all.all and not credits.writing and not credits.lyrics and not credits.music and not credits.arrangements then newall[1] = all.all[1] .. all.all[2] elseif all.writing and not credits.writing and not credits.lyrics and not credits.music then newall[1] = all.writing[1] .. all.writing[2] elseif all.producing and not credits.music and not credits.arrangements then newall[#newall + 1] = all.producing[1] .. all.producing[2] end if all.arrangements and not credits.arrangements then newall[#newall + 1] = all.arrangements[1] .. all.arrangements[2] end end if newall[1] or #desc > 0 then --全○○/コメント行追加 result = result .. '<tr><td colspan="' .. col .. '" style="padding-left:0.5em;"><small style="font-size:100%;">' .. (desc[1] or '') .. (newall[1] and (table.concat(newall, '、') .. '。') or '') .. (desc[2] or '') .. '</small></td></tr>' end --見出し行追加(#列・タイトル列追加) result = result .. '<tr style="text-align:left; font-size:111%;"><th scope="col" style="width:2em; padding-right:0.3em; text-align:right; white-space:nowrap;">#</th><th scope="col" style="width:' .. width.title .. '; padding-left:0.9em; white-space:nowrap;">タイトル</th>' if credits.writing then --作詞・作曲列追加 result = result .. '<th scope="col" style="width:' .. (args.writing_width or (credits.extra and '30%' or '40%')) .. ';">作詞・作曲' .. (credits.writing == true and '' or '・編曲') .. '</th>' --作詞・作曲セル関数再定義 if md then writer = function(x) return '<td itemprop="recordingOf" itemscope itemtype="http://schema.org/MusicComposition"><span itemprop="lyricist composer" itemscope itemtype="http://schema.org/Person"><span itemprop="name">' .. (x.writer or all.writer and all.writer[2] or all.all and all.all[2] or ' ') .. '</span></span></td>' end else writer = function(x) return '<td>' .. (x.writer or all.writer and all.writer[2] or all.all and all.all[2] or ' ') .. '</td>' end end else local disp = function(y) if y then return '' else return 'display:none;' end end --作詞列追加 result = result .. '<th scope="col" style="width:' .. (args.lyrics_width or width.credits) .. ';' .. disp(credits.lyrics) .. '">作詞</th>' --作詞セル関数再定義 if md then lyrics = function(x) return '<td itemprop="recordingOf" itemscope itemtype="http://schema.org/MusicComposition" style="' .. disp(credits.lyrics) .. '"><span itemprop="lyricist" itemscope itemtype="http://schema.org/Person"><span itemprop="name">' .. (x.lyrics or all.lyrics and all.lyrics[2] or x.writer or all.writing and all.writing[2] or all.all and all.all[2] or ' ') .. '</span></span></td>' end else lyrics = function(x) return '<td style="' .. disp(credits.lyrics) .. '">' .. (x.lyrics or all.lyrics and all.lyrics[2] or x.writer or all.writing and all.writing[2] or all.all and all.all[2] or ' ') .. '</td>' end end --作曲列追加 result = result .. '<th scope="col" style="width:' .. (args.music_width or width.credits) .. ';' .. disp(credits.music) .. '">作曲' .. (credits.music == true and '' or '・編曲') .. '</th>' --作曲セル関数再定義 if md then music = function(x) return '<td itemprop="recordingOf" itemscope itemtype="http://schema.org/MusicComposition" style="' .. disp(credits.music) .. '"><span itemprop="composer" itemscope itemtype="http://schema.org/Person"><span itemprop="name">' .. (x.music or all.music and all.music[2] or x.writer or all.writing and all.writing[2] or all.producing and all.producing[2] or all.all and all.all[2] or ' ') .. '</span></span></td>' end else music = function(x) return '<td style="' .. disp(credits.music) .. '">' .. (x.music or all.music and all.music[2] or x.writer or all.writing and all.writing[2] or all.producing and all.producing[2] or all.all and all.all[2] or ' ') .. '</td>' end end end if credits.arrangements then --編曲列追加 result = result .. '<th scope="col" style="width:' .. (args.arrangements_width or width.credits) .. ';">編曲</th>' --編曲セル関数再定義 arranger = function(x) return '<td>' .. (x.arranger or all.arrangements and all.arrangements[2] or all.producing and all.producing[2] or all.all and all.all[2] or ' ') .. '</td>' end end if credits.strings_arrange then result = result .. '<th scope="col" style="width:' .. (args.strings_arrange_width or width.credits) .. ';">ストリングスアレンジ</th>' -- ストリングスアレンジセル関数再定義 strings_arrange = function(x) return '<td>' .. (x.strings_arrange or ' ') .. '</td>' end end if credits.brass_arrange then -- ブラスアレンジ列追加 result = result .. '<th scope="col" style="width:' .. (args.brass_arrange_width or width.credits) .. ';">ブラスアレンジ</th>' -- ブラスアレンジセル関数再定義 brass_arrange = function(x) return '<td>' .. (x.brass_arrange or ' ') .. '</td>' end end if credits.horn_arrange then -- ホーンアレンジ列追加 result = result .. '<th scope="col" style="width:' .. (args.horn_arrange_width or width.credits) .. ';">ホーンアレンジ</th>' -- ホーンアレンジセル関数再定義 horn_arrange = function(x) return '<td>' .. (x.horn_arrange or ' ') .. '</td>' end end if credits.orchestra_arrange then -- オーケストラアレンジ列追加 result = result .. '<th scope="col" style="width:' .. (args.orchestra_arrange_width or width.credits) .. ';">オーケストラアレンジ</th>' -- オーケストラアレンジセル関数再定義 orchestra_arrange = function(x) return '<td>' .. (x.orchestra_arrange or ' ') .. '</td>' end end if credits.remix then -- リミックス列追加 result = result .. '<th scope="col" style="width:' .. (args.remix_width or width.credits) .. ';">リミックス</th>' -- オーケストラアレンジセル関数再定義 remix = function(x) return '<td>' .. (x.remix or ' ') .. '</td>' end end if credits.singer then -- 歌列追加 result = result .. '<th scope="col" style="width:' .. (args.singer_width or width.credits) .. ';">歌</th>' -- オーケストラアレンジセル関数再定義 singer = function(x) return '<td>' .. (x.singer or ' ') .. '</td>' end end if credits.extra then --extra列追加 result = result .. '<th scope="col" style="width:' .. (args.extra_width or width.credits) .. ';">' .. credits.extra .. '</th>' --extraセル関数再定義 extra = function(x) return '<td>' .. (x.extra or ' ') .. '</td>' end end if credits.length then --時間列追加 result = result .. '<th scope="col" style="width:4em; padding-right:0.5em; text-align:right; white-space:nowrap;">時間</th>' --時間セル再定義 if md then length = function(x) return '<td style="padding-right:0.5em; text-align:right; white-space:nowrap;">' .. (x.length and ('<time itemprop="duration" datetime="'.. string.gsub(x.length, '^(%d+):(%d+)$', 'PT%1M%2S') ..'">' .. x.length .. '</time>') or ' ') .. '</td>' end else length = function(x) return '<td style="padding-right:0.5em; text-align:right; white-space:nowrap;">' .. (x.length and ('<time datetime="'.. string.gsub(x.length, '^(%d+):(%d+)$', 'PT%1M%2S') ..'">' .. x.length .. '</time>') or ' ') .. '</td>' end end end result = result .. '</tr>' return result end --[[ 本体部 ]] local function body() local result = '' local trackA = {} --ソート用テーブル for k, v in pairs(track) do trackA[#trackA + 1] = v end table.sort(trackA, function (a, b) return a[1] < b[1] end ) if md then for k, v in ipairs(trackA) do local color = (v[1] % 2 == 0) and '' or '' --偶数/奇数で別色指定 result = result .. '<tr itemprop="track" itemscope itemtype="http://schema.org/MusicRecording" style="background-color:' .. color .. '; vertical-align:top;"><td style="padding-left:0.5em; text-align:right;"><span itemprop="position">' .. (v['#'] or v[1]) .. '</span>.</td><td>' .. (v.title and ('<span itemprop="name">' .. v.title .. '</span>') or 'タイトルなし') .. (v.note and ('<small>(' .. v.note .. ')</small>') or '') .. '</td>' .. writer(v) .. lyrics(v) .. music(v) .. arranger(v) .. strings_arrange(v) .. brass_arrange(v) .. horn_arrange(v) .. orchestra_arrange(v) .. remix(v) .. singer(v) .. extra(v) .. length(v) .. '</tr>' end else for k, v in ipairs(trackA) do local color = (v[1] % 2 == 0) and '' or '' result = result .. '<tr style="background-color:' .. color .. '; vertical-align:top;"><td style="padding-left:0.5em; text-align:right;">' .. (v['#'] or v[1]) .. '.</td><td>' .. (v.title and ('' .. v.title .. '') or 'タイトルなし') .. (v.note and ('<small>(' .. v.note .. ')</small>') or '') .. '</td>' .. writer(v) .. lyrics(v) .. music(v) .. arranger(v) .. strings_arrange(v) .. brass_arrange(v) .. horn_arrange(v) .. orchestra_arrange(v) .. remix(v) .. singer(v) .. extra(v) .. length(v) .. '</tr>' end end return result end --[[ フッタ部(合計時間) ]] local function footer() local total = args.total_length local hour, min, sec = 0, 0, 0 if total == 'auto' then --合計時間計算 for k, v in pairs(track) do if not v.length then v.length = '0:00' end local _min, _sec = string.match(v.length, '(%d+):(%d+)') min, sec = min + _min, sec + _sec end while sec > 59 do min = min + 1 sec = sec - 60 end if sec < 10 then sec = '0' .. sec end total = min .. ':' .. sec end if total and total == string.match(total, '%d*:%d*') then --<time>タグ hour, min, sec = string.match(total, '(%d-):?(%d+):(%d+)') hour = (hour ~= '') and tonumber(hour) or 0 min = hour * 60 + tonumber(min) total = '<time datetime="PT' .. min .. 'M' .. sec .. 'S">'.. min .. ':' .. sec .. '</time>' --合計時間行追加 return '<tr style="text-align:right; font-size:111%;"><th colspan="' .. (col - 1) .. '"><div style="width:7.5em; text-align:left; margin:0 0 0 auto; padding-left:0.5em; white-space:nowrap; font-weight:bold;>合計時間:</div></th><td style="padding-right:0.5em;">'.. total .. '</td></tr>' else return '' end end function p.main(frame) getArgs(frame) col = calc_columns() --number width = calc_width() --table --tableタグで囲んで出力 local table = mw.html.create('table') table :wikitext(header() .. body() .. footer()) --tableタグ内 :attr({class = 'tracklist', id = args.id or ''}) :cssText('display:block; max-width:100%; width:auto; border-spacing:0px; border-collapse:collapse; padding:0.2em; font-size:90%; text-align:left; vertical-align: middle;') if collapsed then --折りたたみ表示追加指定 table :addClass('mw-collapsible mw-collapsed') :cssText('position:relative; overflow:hidden; outline:1px solid #aaa;') end if md then table:attr({itemtype = 'http://schema.org/MusicAlbum'}) end return tostring(table) end -- calc_columns 関数に新しい変数に関する表示可否判定のロジックを追加 local function calc_columns() local col = 2 -- #, タイトル -- ... if credits.strings_arrange then col = col + 1 end if credits.brass_arrange then col = col + 1 end if credits.horn_arrange then col = col + 1 end if credits.orchestra_arrange then col = col + 1 end if credits.remix then col = col + 1 end if credits.singer then col = col + 1 end return col end -- ... -- calc_width 関数に新しい変数に関する列幅の計算ロジックを追加 local function calc_width() local width = {} -- ... if not credits.strings_arrange then col = col + 1 end if not credits.brass_arrange then col = col + 1 end if not credits.horn_arrange then col = col + 1 end if not credits.orchestra_arrange then col = col + 1 end if not credits.singer then col = col + 1 end if not credits.remix then col = col + 1 end return width end return p