local mFileLink = require('Module:File link')local mTableTools = require('Module:TableTools')local mSideBox = require('Module:Side box')local lang = mw.language.new('en')
local p =
local function formatLength(length) -- Formats a duration in seconds in "(h:)mm:ss" (minutes are zero-padded -- only if there are hours). if not length or length
-- Add 0.5 to offset the rounding down local t = lang:getDurationIntervals(length + 0.5,) local s = t.seconds and string.format('%02d', t.seconds) or '00' local m = t.minutes or 0
local span = mw.html.create('span'):addClass('duration') if t.hours then span :tag('span') :addClass('h') :wikitext(t.hours) :done :wikitext(':') m = string.format('%02d', m) end span :tag('span') :addClass('min') :wikitext(m) :done :wikitext(':') :tag('span') :addClass('s') :wikitext(s) :done return tostring(span)end
local function renderRow(filename, title, play, alt, description, start, length, hasImage) -- Renders the HTML for one file description row. if not filename then return nil end
length = formatLength(length) length = length and string.format(' (%s)', length) or
local root = mw.html.create() root:tag('div') :addClass('haudio') :newline :tag('div') :addClass('listen-file-header') :wikitext(string.format('%s%s', filename, title or , length )) :done :newline :tag('div') :wikitext(play ~= 'no' and mFileLink._main or nil ) :done :newline :tag('div') :addClass('description') :wikitext(description) :done :done return tostring(root)end
local function renderTrackingCategories(isPlain, hasMissing, isEmpty, titleObj) -- Renders all tracking categories produced by the template. -- isPlain, hasMissing and isEmpty are passed through from p._main, -- and the titleObj is only used for testing purposes. local cats = local currentTitle = titleObj or mw.title.getCurrentTitle if currentTitle.namespace
function p._main(args) -- Organise the arguments by number. local isPlain = args.plain
local numArgs, missingFiles =, do local origNumArgs = mTableTools.numData(args) origNumArgs[1] = origNumArgs.other -- Overwrite args.filename1 etc. with args.filename etc. origNumArgs = mTableTools.compressSparseArray(origNumArgs) for i, t in ipairs(origNumArgs) do -- Check if the files exist. local obj = t.filename and mw.title.makeTitle(-2, t.filename) if obj and obj.exists then if t.length
-- Render warning local hasMissing = #missingFiles ~= 0 local previewWarning = if hasMissing then for i, v in ipairs(missingFiles) do missingFiles[i] = type(v)
-- Exit early if none exist. if #numArgs
-- Build the arguments for local sbArgs =
-- Class arguments do local class = if isPlain then table.insert(class, 'listen-plain') end if isEmbedded then table.insert(class, 'listen-embedded') end if not hasImage then table.insert(class, 'listen-noimage') end if args.pos
'center' then table.insert(class, 'listen-center') end
sbArgs.class = table.concat(class, ' ') end
-- Image if not isPlain and not isEmbedded then if args.image then sbArgs.image = args.image else local images = sbArgs.image = mFileLink._main end end
-- Text do local header if args.header then header = mw.html.create('div') header:addClass('listen-header') :wikitext(args.header) header = tostring(header) .. '\n' else header = end local text = for i, t in ipairs(numArgs) do text[#text + 1] = renderRow(t.filename, t.title, t.play, t.alt, t.description, t.start, t.length, hasImage ) if numArgs[i + 1] then text[#text + 1] = '
' end end sbArgs.text = header .. table.concat(text) end
-- Below if not isPlain and not isEmbedded and args.help ~= 'no' then sbArgs.below = string.format('
-- Render the side box. local sideBox = mSideBox._main(sbArgs)
-- Render the tracking categories. local trackingCategories = renderTrackingCategories(isPlain, hasMissing)
return previewWarning .. sideBox .. trackingCategoriesend
function p.main(frame) local origArgs = frame:getParent.args local args = for k, v in pairs(origArgs) do if v ~= then args[k] = v end end return p._main(args)end
return p