Module:Cite
Jump to navigation
Jump to search
Generates citations across the wiki to ensure standard formatting. The module accepts several different types of citations and processes each differently, based on the f
table's functions. When the module is called without a type, it acts as a citation needed template.
Documentation
Package items
cite.main(frame)
(function)- Template entrypoint for Template:Cite.
- Parameter:
frame
Scribunto frame object (table) - Returns: Citation text (string)
f.twitter(args)
(function)- Handles Twitter citations. Twitter citations receive arguments in this order:
- Twitter snowflake
- Tweet author's handle
- Citation from the tweet
- (Optional) Timestamp of the tweet's archival
- (Optional) Whether the original tweet link is dead
- Parameter:
args
Citation type arguments (table) - Returns: Citation text (string)
f.game(args)
(function)- Handles citations of text in the game. Game citations receive arguments in this order:
- Quotation
- Quote author and the situation in which they made the quote
- Parameter:
args
Citation type arguments (table) - Returns: Citation text (string)
f.youtube(args)
(function)- Handles citations of YouTube videos. YouTube citations receive arguments in this order:
- YouTube video ID
- Video title
- (Optional) Time at which the video plays
- Parameter:
args
Citation type arguments (table) - Returns: Citation text (string)
f.tumblr(args)
(function)- Handles Tumblr citations. Tumblr citations receive arguments in this order:
- Tumblr name of the author
- Tumblr post ID
- Citation from the post
- Date in YYYY-MM-DD format (or any other standard format)
- Parameter:
args
Citation type arguments (table) - Returns: Citation text (string)
f.code(args)
(function)- Handles citations of the game's code. Code citations receive arguments in this order:
- GML script name
- (Optional) Starting line number
- (Optional) Ending line number
- Parameter:
args
Citation type arguments (table) - Returns: Citation text (string)
- See also: https://github.com/KockaAdmiralac/deltarune-viewer
f.news(args)
(function)- Handles citations from news sources. News citations receive arguments in this order:
- Excerpt from the news
- News post title
- News site name
- News post URL
- News post date
- (Optional) First name of the author
- (Optional) Last name of the author
- Parameter:
args
Citation type arguments (table) - Returns: Citation text (string)
f.twitch(args)
(function)- Handles citations from Twitch clips. Twitch clip citations receive arguments in this order:
- Clip URL segment (the part after https://clips.twitch.tv/)
- Clip title
- Twitch username of the streamer
- Stream date (not clipping date)
- Parameter:
args
Citation type arguments (table) - Returns: Citation text (string)
--- Generates citations across the wiki to ensure standard formatting.
-- The module accepts several different types of citations and processes each
-- differently, based on the <code>f</code> table's functions. When the module
-- is called without a type, it acts as a citation needed template.
-- @module cite
-- @alias p
-- @require Dev:Date
-- @require Dev:User error
-- @require Dev:Yesno
-- @require Module:Tags
-- @author [[User:KockaAdmiralac|KockaAdmiralac]]
-- <nowiki>
local p = {}
-- Module dependencies
local Date = require('Dev:Date')
local userError = require('Dev:User error')
local yesno = require('Dev:Yesno')
local tags = require('Module:Tags')
local data = mw.loadData('Module:Cite/data')
local title = mw.title.getCurrentTitle()
-- Private logic.
--- Wrapper for <code>userError</code> that places the page under the Pages with
-- user errors category.
-- @function err
-- @param {string} text Text to display as an error
-- @return {string} Wikitext with the error and category
-- @local
local function err(text)
return userError(text, 'Pages with user errors')
end
--- Checks whether a given date string is a valid date.
-- @function valid_date
-- @param {string} d Date string to check
-- @return {bool} Whether the string is a valid date
-- @local
function valid_date(d)
return pcall(function()
Date(d)
end)
end
--- Table of possible citation types and the way they are processed.
-- Each type has a function associated with it that gets passed the arguments
-- after the type, does validation of these arguments and returns the whole
-- citation text.
-- @table cite_functions
-- @alias f
local f = {}
--- Handles Twitter citations.
-- Twitter citations receive arguments in this order:
-- * Twitter snowflake
-- * Tweet author's handle
-- * Citation from the tweet
-- * (Optional) Timestamp of the tweet's archival
-- * (Optional) Whether the original tweet link is dead
-- @function f.twitter
-- @param {table} args Citation type arguments
-- @return {string} Citation text
function f.twitter(args)
-- Check validity of arguments
if not args[1] or not tonumber(args[1]) then
return err('Tweet snowflake invalid or not specified')
end
if not args[2] or not args[3] then
return err('Tweet author or citation not specified')
end
-- Twitter snowflake date extraction
-- Credits: https://github.com/client9/snowflake2time
local snowflake = tonumber(args[1])
local epoch = math.floor(snowflake / 4194304 + 1288834974657)
local date1 = Date(math.floor(epoch / 1000))
-- Format citation
local deadurl = yesno(args[5], false)
local archived = yesno(args[4], true)
local str = {
'\'\'',
args[3],
'\'\' - ['
}
if deadurl and archived then
table.insert(str, 'https://web.archive.org/web/')
table.insert(str, args[4])
table.insert(str, '/')
end
table.insert(str, 'https://twitter.com/')
table.insert(str, args[2])
table.insert(str, '/status/')
table.insert(str, args[1])
if data.twitter[args[2]] then
table.insert(str, ' ')
table.insert(str, data.twitter[args[2]])
table.insert(str, ' (@')
table.insert(str, args[2])
table.insert(str, ')')
else
table.insert(str, ' @')
table.insert(str, args[2])
end
table.insert(str, ' on Twitter,] ')
table.insert(str, date1:fmt('%B %d, %Y.'))
if deadurl then
if archived then
table.insert(str, ' Archived on ')
table.insert(str, Date(args[4]):fmt('%B %d, %Y.'))
else
table.insert(str, ' \'\'\'[deleted]\'\'\'')
end
end
return table.concat(str)
end
--- Handles citations of text in the game.
-- Game citations receive arguments in this order:
-- * Quotation
-- * Quote author and the situation in which they made the quote
-- @function f.game
-- @param {table} args Citation type arguments
-- @return {string} Citation text
function f.game(args)
if not args[1] then
return err('Quote not specified')
end
if not args[2] then
return err('Quote author not specified')
end
return table.concat({
'\'\'',
tags.replace(args[1]),
'\'\' - ',
args[2]
})
end
--- Handles citations of YouTube videos.
-- YouTube citations receive arguments in this order:
-- * YouTube video ID
-- * Video title
-- * (Optional) Time at which the video plays
-- @function f.youtube
-- @param {table} args Citation type arguments
-- @return {string} Citation text
function f.youtube(args)
if not args[1] or not args[2] then
return err('Video ID or title not specified')
end
local str = {
'\'\'',
args[2],
'\'\' - [https://youtu.be/',
args[1]
}
if args[3] then
table.insert(str, '?t=')
table.insert(str, args[3])
end
table.insert(str, ' YouTube]')
return table.concat(str)
end
--- Handles Tumblr citations.
-- Tumblr citations receive arguments in this order:
-- * Tumblr name of the author
-- * Tumblr post ID
-- * Citation from the post
-- * Date in YYYY-MM-DD format (or any other standard format)
-- @function f.tumblr
-- @param {table} args Citation type arguments
-- @return {string} Citation text
function f.tumblr(args)
if not args[1] or not args[3] then
return err('Author or quote not specified')
end
if not args[2] or not tonumber(args[2]) then
return err('Post ID invalid or not specified')
end
if not args[4] or not valid_date(args[4]) then
return err('Date invalid or not specified')
end
return table.concat({
'\'\'',
tags.replace(args[3]),
'\'\' - [http://',
args[1],
'.tumblr.com/post/',
args[2],
' ',
args[1],
' on Tumblr,] ',
Date(args[4]):fmt('%B %d, %Y.')
})
end
--- Handles citations of the game's code.
-- Code citations receive arguments in this order:
-- * GML script name
-- * (Optional) Starting line number
-- * (Optional) Ending line number
-- @function f.code
-- @param {table} args Citation type arguments
-- @return {string} Citation text
-- @see https://github.com/KockaAdmiralac/deltarune-viewer
function f.code(args)
local str = {}
if not args[1] then
return err('Script name not specified')
end
if (args[2] and not tonumber(args[2])) or (args[3] and not tonumber(args[3])) then
return err('Line number is not a number')
end
if data.script_repo ~= nil then
str = {
'[',
data.script_repo,
'/',
args[1],
'.html',
}
if args[2] then
table.insert(str, '#L')
table.insert(str, args[2])
end
table.insert(str, ' ')
table.insert(str, args[1])
table.insert(str, ' script]')
else
str = {
args[1],
' script'
}
end
if args[2] then
table.insert(str, ', line')
if args[3] then
table.insert(str, 's ')
table.insert(str, args[2])
table.insert(str, '–')
table.insert(str, args[3])
else
table.insert(str, ' ')
table.insert(str, args[2])
end
end
return table.concat(str)
end
--- Handles citations from news sources.
-- News citations receive arguments in this order:
-- * Excerpt from the news
-- * News post title
-- * News site name
-- * News post URL
-- * News post date
-- * (Optional) First name of the author
-- * (Optional) Last name of the author
-- @function f.news
-- @param {table} args Citation type arguments
-- @return {string} Citation text
function f.news(args)
if not args[1] then
return err('Relevant news post excerpt not specified')
end
if not args[2] then
return err('News post title not specified')
end
if not args[3] then
return err('News site name not specified')
end
if not args[4] then
return err('News post URL not specified')
end
if not args[5] or not valid_date(args[5]) then
return err('News post date invalid or not specified')
end
local author = {}
if args[6] then
if args[7] then
table.insert(author, args[7])
table.insert(author, ', ')
end
table.insert(author, args[6])
table.insert(author, ', ')
end
return table.concat({
'\'\'',
tags.replace(args[1]),
'\'\' - [',
args[4],
' ',
args[2],
'] (',
table.concat(author),
Date(args[5]):fmt('%B %d, %Y.'),
') \'\'',
args[3],
'\'\'.'
})
end
--- Handles citations from Twitch clips.
-- Twitch clip citations receive arguments in this order:
-- * Clip URL segment (the part after https://clips.twitch.tv/)
-- * Clip title
-- * Twitch username of the streamer
-- * Stream date (not clipping date)
-- @function f.twitch
-- @param {table} args Citation type arguments
-- @return {string} Citation text
function f.twitch(args)
if not args[1] then
return err('Clip URL segment not specified')
end
if not args[2] then
return err('Clip title not specified')
end
if not args[3] then
return err('Streamer username not specified')
end
if not args[4] or not valid_date(args[4]) then
return err('Stream date invalid or not specified')
end
return table.concat({
'"\'\'[https://clips.twitch.tv/',
args[1],
' "',
args[2],
',]\'\'" a clip from [https://twitch.tv/',
mw.ustring.lower(args[3]),
' @',
args[3],
'\'s] Twitch stream on ',
Date(args[4]):fmt('%B %d, %Y.')
})
end
-- Package items.
--- Template entrypoint for [[Template:Cite]].
-- @function p.main
-- @param {table} frame Scribunto frame object
-- @return {string} Citation text
function p.main(frame)
local args = frame:getParent().args
local t = args[1]
if t then
if f[t] then
local nargs = {}
for i, v in ipairs(args) do
if i > 1 then
nargs[i - 1] = v
end
end
return f[t](nargs);
else
return err('Invalid citation type specified')
end
else
-- {{cite}} was used
local str = '<sup>[[[w:c:ut:Project:Manual of Style#Citation needed|<span title="This statement needs proper citation.">citation needed</span>]]]</sup>'
if title.namespace == 0 or title.namespace == 14 then
return str .. '[[Category:Articles lacking sources]]'
else
return str
end
end
end
return p