Jump to content

Module:Spoken Wikipedia

Permanently protected module
From Wikipedia, the free encyclopedia

local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local Date = require('Module:Date')._Date
local lang = mw.language.new('en')
local cfg = mw.loadData('Module:Spoken Wikipedia/configuration')

p = {}

local function wikiError(message)
	local ret = mw.html.create('div')
		:addClass(cfg.i18n.class.err)
		:wikitext(message)
		:done()
	return tostring(ret)
end

local function category(c, nocat)
	if nocat then
		return ''
	else
		return c
	end
end

local function formatPageText(page)
	if page then
		return '<span class="fn">[[' .. page .. ']]</span>'
	end
	if mw.title.getCurrentTitle().namespace == 0 then
		return cfg.i18n.this_article
	else
		return cfg.i18n.this_page
	end
end

local function formatFileLength(filenames)
	local length = 0
	for _, filename in ipairs(filenames) do
		local fileTitle = mw.title.new(filename, 'Media')
		if fileTitle and fileTitle.file and fileTitle.file.exists then
			length = length + fileTitle.file.length
		end
	end

	-- Add 30 to offset the rounding down
	local intervals = lang:getDurationIntervals(length + 30, { 'hours', 'minutes' })
	local ret = string.format(
		'<span class="min">%s</span> %s',
		intervals.minutes or 0,
		intervals.minutes == 1 and cfg.i18n.minute or cfg.i18n.minutes
	)
	if intervals.hours then
		ret = string.format(
			'<span class="h">%s</span> %s and %s',
			intervals.hours,
			intervals.hours == 1 and cfg.i18n.hour or cfg.i18n.hours,
			ret
		)
	end
	return '<span class="duration">' .. ret .. '</span>'
end

local function formatHeader(filenames, page)
	local listento = mw.html.create('span')
		:addClass(cfg.i18n.class.listento)
		:wikitext(string.format(
			cfg.i18n.listento,
			formatPageText(page)
		))
		:done()
	
	local file_length
	if #filenames > 1 then
		file_length = string.format(
			cfg.i18n.n_files_length,
			tostring(#filenames),
			formatFileLength(filenames)
		)
	else
		file_length = string.format(
			cfg.i18n.one_file_length,
			formatFileLength(filenames)
		)
	end
	return mw.html.create('div')
		:addClass(cfg.i18n.class.header)
		:node(listento)
		:wikitext(file_length)
		:done()
end

local function formatIcon()
	return mw.html.create('div')
		:addClass(cfg.i18n.class.icon)
		:wikitext(cfg.i18n.icon)
		:done()
end

local function formatFiles(filenames, nocat)
	if #filenames == 0 then
		return wikiError(cfg.i18n.err.no_filename) ..
			category(cfg.i18n.cat.no_filename, nocat)
	end
	
	-- TODO: the else branch really wants to be a mw.html <ol> object rather than wikitext
	-- version of the same, so that we can style the numbers nicer
	local files = {}
	if #filenames == 1 then
		table.insert(files, string.format(cfg.i18n.one_file, filenames[1]))
	else
		for i, filename in ipairs(filenames) do
			table.insert(files, string.format(cfg.i18n.n_files, filename, i))
		end
	end

	return mw.html.create('div')
		:addClass(cfg.i18n.class.files)
		:wikitext(table.concat(files))
		:done()
		:newline()
end

local function formatDateText(frame, dateArg, nocat)
	local d = dateArg and Date(dateArg) or nil
	return d and frame:expandTemplate{
		title = 'Start date', args = {
			d.year,
			d.month,
			d.day,
			df='y'
		}
	} or (wikiError(cfg.i18n.err.no_date) .. category(cfg.i18n.cat.no_date, nocat))
end

local function formatDisclaimer(frame, filenames, page, dateArg, nocat)
	local thisFileText = ''
	local disclaimer
	if #filenames == 1 then
		thisFileText = filenames[1]
		disclaimer = cfg.i18n.one_file_disclaimer
	else
		disclaimer = cfg.i18n.n_files_disclaimer
	end
	return mw.html.create('div')
		:addClass(cfg.i18n.class.disclaimer)
		:wikitext(string.format(
			disclaimer,
			thisFileText,
			formatPageText(page),
			formatDateText(frame, dateArg, nocat)
		))
		:done()
end

local function formatFooter()
	return mw.html.create('div')
		:addClass(cfg.i18n.class.footer)
		:wikitext(cfg.i18n.footer)
		:done()
end

local function formatTopicon(frame, filenames)
	local wikilink
	if #filenames > 0 then
		wikilink = 'File:' .. filenames[1]
	else
		wikilink = cfg.i18n.topicon_multiwikilink
	end
	return frame:expandTemplate{
		title = "Top icon",
		args = {
			imagename = 'Sound-icon.svg',
			wikilink = wikilink,
			text = 'Listen to this article',
			id = 'spoken-icon'
		}
	}
end

local function extractFilenames(args)
	local filenames = {}
	for key, rawValue in ipairs(args) do
		local value = mw.text.trim(rawValue)
		if type(key) == "number" and value ~= '' then
			table.insert(filenames, value)
		end
	end
	return filenames
end

local function sidebox(nodes)
	root = mw.html.create('div')
		:addClass(cfg.i18n.class.box)
	for _, node in ipairs(nodes) do
		root:node(node)
	end
	return root
end

function main(frame)
	local args = getArgs(frame)

	-- Mandatory parameters
	local filenames = extractFilenames(args)
	local dateArg = args['date']
	-- Optional parameters
	local page = args['page']
	local nocat = yesno(args['nocat'], false) or false

	local root = sidebox({
		formatHeader(filenames, page),
		formatFiles(filenames, nocat),
		formatIcon(),
		formatDisclaimer(frame, filenames, page, dateArg, nocat),
		formatFooter()
	})

	if mw.title.getCurrentTitle().namespace == 0 then
		root:wikitext(formatTopicon(frame, filenames))
		root:wikitext(category(cfg.i18n.cat.articles, nocat))
	end

	return frame:extensionTag{
		name = 'templatestyles', args = { src = cfg.templatestyles }
	} .. tostring(root)
end

p.main = main

return p
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy