Module:Spoken Wikipedia

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 = 'Gnome-mime-sound-openclipart.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

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.