Module:Cite tweet

From Zoophilia Wiki
Jump to navigationJump to search

Usage

This module implements {{Cite tweet}}, as {{#invoke:{{BASEPAGENAME}}|main}}.

In templates, or in articles which cannot otherwise fit within the template count limit, it may be called directly as {{#invoke:{{BASEPAGENAME}}||normal arguments for cite tweet}}, i.e. exactly the same as {{Cite tweet}}, except for an empty first parameter.

In all normal articles, use {{Cite tweet}} instead.



local p = {}
local TwitterSnowflake = require('Module:TwitterSnowflake')
local CiteWeb = require('Module:Cite web')['']

local err_msgs_t = {  -- A sequence of snowflake date error messages; all must be terminated with a semicolon (;).
	' <kbd>&#124;date=</kbd> / <kbd>&#124;number=</kbd> mismatch;',	 -- [1]
	' <kbd>&#124;date=</kbd> required;',							 -- [2]
	' Invalid <kbd>&#124;number=</kbd>;',							 -- [3]
	' Missing or empty <kbd>&#124;number=</kbd>;',					 -- [4]
	' Missing or empty <kbd>&#124;user=</kbd>;'						 -- [5]
	}


-- MAIN
p.main = function(frame)
	return p[''](frame)
end

-- SUPPRESS URL IN TITLE
-- This function searches for and suppresses URLs in the title, script-title and trans-title parameters,
-- so that Cite web won't emit error messages when parsed. In the rendering, URLs are correctly formed,
-- as they were in the original tweet. The function looks for valid schemes, wrapping them in nowiki tags.
local function suppress_url_in_title (frame, title)
	local schemes = {  -- Schemes commonly found in tweets.
		'https://',
		'http://',
		'ftp://',
		}

	if title then  -- When there is a title, suppress any URLs with known schemes, else abandon.
		-- Spin through the list of schemes looking for a match.
		for _, scheme in ipairs (schemes) do
			-- Replace the scheme with its nowiki'd form (a strip marker).
			title = title:gsub (scheme, frame:callParserFunction ('#tag', {'nowiki', scheme}));
		end
	end

	-- Return title, modified or not.
	return title;
end


-- DATE NUMBER URL GET
-- Extract date and number parameter values, if present. Extract date from number and compare to date.
-- Construct URL for Cite web from the base URL and number and user. Returns nothing; adds date, number,
-- URL to <cite_args_t>; adds error message(s) to <errors_t>.

local function date_number_url_get (args_t, cite_args_t, errors_t)
	local err_msg_index;

	-- Initialize with minimal base URL because Cite web requires it.
	cite_args_t.url = 'https://x.com/';
	if not args_t.user then
		-- Error: Missing or empty user parameter.
		table.insert (errors_t, err_msgs_t[5]);
	end

	if not args_t.date and not args_t.number then
		-- Error: Missing or empty number parameter.
		err_msg_index = 4;
	-- Have number parameter without date? Use number.
	elseif tonumber (args_t.number) then
		if tonumber(args_t.number) then
			cite_args_t.date = args_t.date or (args_t.number and TwitterSnowflake.snowflakeToDate{ args = {id_str = args_t.number} });
		else
			cite_args_t.date = args_t.date;
		end
			cite_args_t.number = args_t.number;

			-- Number parameter appears to have a valid value; if user parameter has a value.
			if args_t.user then
				-- Construct URL for Cite web.
				cite_args_t.url = cite_args_t.url .. args_t.user .. '/status/' .. args_t.number;
			end
	elseif args_t.number then
		-- Error: Invalid number that couldn't be converted to a number.
		err_msg_index = 3;
	-- Date parameter without number; use date.
	elseif not args_t.number then
		-- Date paramter has a value, use it.
		cite_args_t.date = args_t.date;
		-- Error: Missing or empty number parameter.
		err_msg_index = 4;
	end

	if err_msg_index then
		-- Invalid number or missing necessary parameters, so abandon.
		table.insert (errors_t, err_msgs_t[err_msg_index]);
		return;
	end

	-- Returns error message index number on error; else nil.
	err_msg_index = TwitterSnowflake.datecheck ({ args = {
		id_str	= args_t.number or '',
		date	= args_t.date or '',
		-- These numbers are indexes into <err_msgs_t>, to override snowflake default error messages.
		error1	= 1,
		-- Done this way to avoid long string comparison looking for the undated-pre-twitter-epoch-post message.
		error2  = 2,
		error3	= 3
		}});

	-- When there's no date and it was posted before the Twitter epoch.
	if	2 == err_msg_index then
		-- Suppress default date because Cite tweet should not claim in its own voice that an undated post was made on 2010-11-04.
		cite_args_t.date = nil;
	end
	
	-- Add error message.
	table.insert (errors_t, err_msgs_t[err_msg_index]);
end


-- p['']
-- Construct parameter set for Cite web from Cite tweet parameters, and do some error checking.
p[''] = function(frame)
	local args_t = require ('Module:Arguments').getArgs (frame);

	local cite_args_t = {
		title = suppress_url_in_title (frame, args_t.title),
		['script-title'] = suppress_url_in_title (frame, args_t['script-title']),
		['trans-title'] = suppress_url_in_title (frame, args_t['trans-title']),
		language = args_t.language,
		last1 = args_t.last1 or args_t.last,
		first1 = args_t.first1 or args_t.first,
		author1 = args_t.author1 or args_t.author,
		['author-link'] = args_t['author-link'] or args_t.authorlink,
		others = args_t.retweet and ('Retweeted by ' .. args_t.retweet),
		via = args_t.link == 'no' and 'Twitter' or '[[wikipedia:Twitter|Twitter]]',
		type = args_t.link == 'no' and 'Tweet' or '[[wikipedia:Tweet (social media)|Tweet]]',
		-- Why the location parameter? Tweets are online; there is no publication place.
		location = args_t.location,
		['access-date'] = args_t['access-date'] or args_t.accessdate,
		['archive-date'] = args_t['archive-date'] or args_t.archivedate,
		['archive-url'] = args_t['archive-url'] or args_t.archiveurl,
		['url-status'] = args_t['url-status'],
		['url-access'] = args_t['url-access'],
		quote = args_t.quote,
		ref = args_t.ref,
		df = args_t.df,
		mode = args_t.mode
		}

	-- Initialize sequence of error messages with style tag.
	local errors_t = {'<span class="cs1-visible-error citation-comment"> <kbd>{{[[Template:Cite tweet|Cite tweet]]}}</kbd>:'};
	-- Add date, number and url parameters to <cite_args_t>.
	date_number_url_get (args_t, cite_args_t, errors_t);

	-- Concatenate last parameter with first for author-mask.
	local author = ((cite_args_t.last1 and cite_args_t.first1) and cite_args_t.last1 .. ', ' .. cite_args_t.first1) or
		-- Only last parameter for author-mask.
		(cite_args_t.last1 and cite_args_t.last1) or
		-- Strip author or author1 parameters of accept-as-written markup for author-mask.
		(cite_args_t.author1 and cite_args_t.author1:gsub('^%(%((.+)%)%)$', '%1'));

	if author and args_t.user then
		-- Concatenate <author> and user parameter into author-mask.
		cite_args_t['author-mask'] = author .. ' [@' .. (args_t.user or '') .. ']'
	elseif args_t.user then
		-- Just the user name for CS1 & CS2 template metadata.
		cite_args_t.author1 = '((' .. args_t.user .. '))';
		-- Make a mask for display.
		cite_args_t['author-mask'] = '@' .. args_t.user;
	-- Here when neither <author> nor user are available.
	else
		-- So unset.
		cite_args_t.author1 = nil;
	end

	-- Overwrite frame arguments.
	frame.args = cite_args_t;
	-- Render the template.
	local rendering = CiteWeb (frame);

-- Error messaging
	-- errors_t[2] is nil when there are no errors.
	if errors_t[2] then
		-- Rendered Cite web template with errors will have this string.
		if rendering:find ('cs1-visible-error', 1, true) then
			-- Insert a semicolon to terminate CS1 & CS2 error message string.
			errors_t[1] = errors_t[1]:gsub ('> <', '>; <');
		end

		-- Replace trailing semicolon with a help link.
		errors_t[#errors_t] = errors_t[#errors_t]:gsub (';$',' ([[Template:Cite_tweet#Error_detection|help]])');
		table.insert (errors_t, '</span>');										-- close style span tag
		-- In the Main namespace, only.
		if mw.title.getCurrentTitle():inNamespace (0) then
			-- Add error tracking category.
			table.insert (errors_t, '[[Category:Cite tweet templates with errors]]');
		end

		-- Append error messaging, help links and categories.
		rendering = rendering .. table.concat (errors_t);
	end
	return rendering;
end

return p