Module:Cite tweet: Difference between revisions

From The Goon Show Depository

en>Nardog
(support |quote)
 
m (1 revision imported)
 
(2 intermediate revisions by 2 users not shown)
Line 3: Line 3:
local CiteWeb = require('Module:Cite web')['']
local CiteWeb = require('Module:Cite web')['']


local function _if(arg)
local err_msgs_t = { -- a sequence of snowflake date error messages; all must be terminated with a semicolon (;)
return arg and arg ~= '' or nil
' <kbd>&#124;date=</kbd> / <kbd>&#124;number=</kbd> mismatch;', -- [1]
end
' <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]
}
 
 
--[[--------------------------< M A I N >----------------------------------------------------------------------
]]


p.main = function(frame)
p.main = function(frame)
frame.args = frame:getParent().args
return p[''](frame)
return p[''](frame)
end
end


p[''] = function(frame)
--[[--------------------------< S U P P R E S S _ U R L _ I N _ T I T L E >------------------------------------
local args = frame.args
 
local cite_args = {
This function searches for and suppresses urls in |title=, |script-title=, and |trans-title= parameters so that
url = 'https://twitter.com/' .. ((args.user and args.number) and (args.user .. '/status/' .. args.number) or ''),
{{cite web}} won't emit 'External link in |title=' error messages when rendered In the redering, urls are correctly
title = (args.title or ''):gsub('https*://', ''),
formed as they were in the original tweet. The function looks for valid schemes and then wraps them in
['script-title'] = args['script-title'],
<nowiki>..</nowiki> tags.
['trans-title'] = args['trans-title'],
 
language = args.language,
]]
['author-link'] = args['author-link'] or args.authorlink,
 
others = _if(args.retweet) and ('Retweeted by ' .. args.retweet),
local function suppress_url_in_title (frame, title)
via = args.link == 'no' and 'Twitter' or '[[Twitter]]',
local schemes = { -- schemes commonly found in tweets
type = 'Tweet',
'https://',
location = args.location,
'http://',
['access-date'] = args['access-date'] or args.accessdate,
'ftp://',
['archive-date'] = args['archive-date'] or args.archivedate,
}
['archive-url'] = args['archive-url'] or args.archiveurl,
 
['url-status'] = args['url-status'] or args['dead-url'] or args.deadurl,
if title then -- when there is a title, suppress any urls with known schemes; abandon else
quote = args.quote,
for _, scheme in ipairs (schemes) do -- spin through the list of schemes looking for a match
ref = args.ref,
title = title:gsub (scheme, frame:callParserFunction ('#tag', {'nowiki', scheme})); -- replace the scheme with its nowiki'd form (a strip marker)
df = args.df
end
}
if _if(args.last1 or args.last) then
cite_args.author = (args.last1 or args.last) ..
(_if(args.first1 or args.first) and (', ' .. (args.first1 or args.first)) or '') ..
' [@' .. (args.user or '') .. ']'
elseif _if(args.author1 or args.author) then
cite_args.author = (args.author1 or args.author) .. ' [@' .. (args.user or '') .. ']'
elseif _if(args['author-link']) then
cite_args.author = args['author-link'] .. ' [@' .. (args.user or '') .. ']'
else
cite_args.author = '@' .. (args.user or '')
end
end
if cite_args.author:find ('[Tt]witter') then
 
cite_args.author = '((' .. cite_args.author .. '))'
return title; -- done; return <title> modified or not
end
 
 
--[[--------------------------< D A T E _ N U M B E R _ U R L _ G E T >----------------------------------------
 
extract |date= and |number= parameter values if present.  Extract date from |number= and compare to |date=.
 
contruct |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;
 
cite_args_t.url = 'https://x.com/';         -- initialize with minimal base url because {{cite web}} requires |url=
if not args_t.user then
table.insert (errors_t, err_msgs_t[5]); -- error: missing or empty |user=
end
end
if _if(tonumber(args.number)) then
 
cite_args.date = args.date or (_if(args.number) and TwitterSnowflake.snowflakeToDate{ args = {id_str = args.number} })
if not args_t.date and not args_t.number then
else
err_msg_index = 4; -- error: missing or empty |number=
cite_args.date = args.date
elseif tonumber (args_t.number) then -- |number= without |date=? use number
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;
 
if args_t.user then -- |number= appears to have a valid value; if |user= has a value
cite_args_t.url = cite_args_t.url .. args_t.user .. '/status/' .. args_t.number; -- construct |url= for {{cite web}}
end
elseif args_t.number then -- |number= with a value that can't be converted to a number; invalid
err_msg_index = 3; -- error: invalid number (couldn't convert to number)
elseif not args_t.number then -- |date= without |number= use date
cite_args_t.date = args_t.date; -- |date= has a value, use it
err_msg_index = 4; -- error: missing or empty |number=
end
end
 
frame.args = cite_args
if err_msg_index then
local output = CiteWeb(frame)
table.insert (errors_t, err_msgs_t[err_msg_index]); -- invalid number or missing necessary parameters so abandon
frame.args = args
return;
-- Error checking
local error_template = '<span class="cs1-visible-error citation-comment">%s</span>'
local errors = {}
if not (_if(args.title) or _if(args['script-title']) or args.user or args.number or args.date) then
-- No title; error message is provided by CS1 module.
errors[1] = ';'
end
end
if not _if(args.user) then
 
errors[1 + #errors] = ' Missing or empty <kbd>&#124;user=</kbd>;'
err_msg_index = TwitterSnowflake.datecheck ({ args = { -- returns error message index number on error; nil else
id_str = args_t.number or '',
date = args_t.date or '',
error1 = 1, -- these numbers are indexes into <err_msgs_t> to override snowflake default error messages
error2  = 2, -- done this way to avoid long string comparison looking for
error3 = 3 -- the undated-pre-twitter-epoch-post message
}});
 
if 2 == err_msg_index then -- when no date and posted before twitter epoch
cite_args_t.date = nil; -- suppress default date because {{cite tweet}} should not claim in its own voice that the undated post was posted 2010-11-04
end
end
if not _if(args.number) then
errors[1 + #errors] = ' Missing or empty <kbd>&#124;number=</kbd>;'
table.insert (errors_t, err_msgs_t[err_msg_index]); -- add error message
end
 
 
--[[--------------------------< p[''] >------------------------------------------------------------------------
 
construct parameter set for {{cite web}} from {{cite tweet}} parameters;  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 '[[Twitter]]',
type = args_t.link == 'no' and 'Tweet' or '[[Tweet (social media)|Tweet]]',
location = args_t.location, -- why |location=?  tweets are online; there is no publication place
['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
}
 
local errors_t = {'<span class="cs1-visible-error citation-comment"> <kbd>{{[[Template:Cite tweet|Cite tweet]]}}</kbd>:'}; -- initialize sequence of error messages with style tag
date_number_url_get (args_t, cite_args_t, errors_t); -- add |date=, |number=, |url= to <cite_args_t>
 
local author = ((cite_args_t.last1 and cite_args_t.first1) and cite_args_t.last1 .. ', ' .. cite_args_t.first1) or -- concatenate |last= with |first= for |author-mask=
(cite_args_t.last1 and cite_args_t.last1) or -- only |last= for |author-mask=
(cite_args_t.author1 and cite_args_t.author1:gsub('^%(%((.+)%)%)$', '%1')); -- |author= or |author1= stripped of accept-as-written markup for |author-mask=
 
if author and args_t.user then
cite_args_t['author-mask'] = author .. ' [@' .. (args_t.user or '') .. ']' -- concatenate <author> and |user= into |author-mask=
elseif args_t.user then
cite_args_t.author1 = '((' .. args_t.user .. '))'; -- just the user name for cs1|2 metadata
cite_args_t['author-mask'] = '@' .. args_t.user; -- make a mask for display
else -- here when neither <author> nor |user=
cite_args_t.author1 = nil; -- so unset
end
end
errors[1 + #errors] = TwitterSnowflake.datecheck{ args = {
 
id_str = args.number or '',
frame.args = cite_args_t; -- overwrite frame arguments
date = args.date or '',
local rendering = CiteWeb (frame); -- render the template
error1 = ' <kbd>&#124;date=</kbd> mismatches calculated date from <kbd>&#124;number=</kbd> by two or more days;',
 
error2  = ' Missing or empty <kbd>&#124;date=</kbd>, and posted before November 4, 2010;',
---------- error messaging ----------
error3 = ' Invalid <kbd>&#124;number=</kbd> parameter;'
if errors_t[2] then -- errors_t[2] nil when no errors
}}
if rendering:find ('cs1-visible-error', 1, true) then -- rendered {{cite web}} with errors will have this string
if errors[1] then
errors_t[1] = errors_t[1]:gsub ('> <', '>; <'); -- insert semicolon to terminate cs1|2 error message string
local last = errors[#errors]
errors[#errors] = last:sub(1, #last - 1) .. ' ([[Template:Cite_tweet#Error_detection|help]])'
local error_out = error_template:rep(#errors):format(unpack(errors))
if mw.title.getCurrentTitle():inNamespace(0) then
error_out = error_out .. '[[Category:Cite tweet templates with errors]]'
end
end
output = output .. error_out
 
errors_t[#errors_t] = errors_t[#errors_t]:gsub (';$',' ([[Template:Cite_tweet#Error_detection|help]])'); -- replace trailing semicolon with help link
table.insert (errors_t, '</span>'); -- close style span tag
if mw.title.getCurrentTitle():inNamespace (0) then -- mainspace only
table.insert (errors_t, '[[Category:Cite tweet templates with errors]]'); -- add error category
end
 
rendering = rendering .. table.concat (errors_t); -- append error messaging, help links and catagories
end
end
return output
return rendering;
end
end


return p
return p

Latest revision as of 15:12, 28 September 2024

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]
	}


--[[--------------------------< M A I N >----------------------------------------------------------------------
]]

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

--[[--------------------------< S U P P R E S S _ U R L _ I N _ T I T L E >------------------------------------

This function searches for and suppresses urls in |title=, |script-title=, and |trans-title= parameters so that
{{cite web}} won't emit 'External link in |title=' error messages when rendered In the redering, urls are correctly
formed as they were in the original tweet.  The function looks for valid schemes and then wraps them in
<nowiki>..</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; abandon else
		for _, scheme in ipairs (schemes) do									-- spin through the list of schemes looking for a match
			title = title:gsub (scheme, frame:callParserFunction ('#tag', {'nowiki', scheme}));	-- replace the scheme with its nowiki'd form (a strip marker)
		end
	end

	return title;																-- done; return <title> modified or not
end


--[[--------------------------< D A T E _ N U M B E R _ U R L _ G E T >----------------------------------------

extract |date= and |number= parameter values if present.  Extract date from |number= and compare to |date=.

contruct |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;

	cite_args_t.url = 'https://x.com/';									        -- initialize with minimal base url because {{cite web}} requires |url=
	if not args_t.user then
		table.insert (errors_t, err_msgs_t[5]);									-- error: missing or empty |user=
	end

	if not args_t.date and not args_t.number then
		err_msg_index = 4;														-- error: missing or empty |number=
	elseif tonumber (args_t.number) then										-- |number= without |date=? use number
		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;

			if args_t.user then													-- |number= appears to have a valid value; if |user= has a value
				cite_args_t.url = cite_args_t.url .. args_t.user .. '/status/' .. args_t.number;	-- construct |url= for {{cite web}}
			end
	elseif args_t.number then													-- |number= with a value that can't be converted to a number; invalid
		err_msg_index = 3;														-- error: invalid number (couldn't convert to number)
	elseif not args_t.number then												-- |date= without |number= use date
		cite_args_t.date = args_t.date;											-- |date= has a value, use it
		err_msg_index = 4;														-- error: missing or empty |number=
	end

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

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

	if	2 == err_msg_index then													-- when no date and posted before twitter epoch
		cite_args_t.date = nil;													-- suppress default date because {{cite tweet}} should not claim in its own voice that the undated post was posted 2010-11-04
	end
	
	table.insert (errors_t, err_msgs_t[err_msg_index]);							-- add error message
end


--[[--------------------------< p[''] >------------------------------------------------------------------------

construct parameter set for {{cite web}} from {{cite tweet}} parameters;  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 '[[Twitter]]',
		type = args_t.link == 'no' and 'Tweet' or '[[Tweet (social media)|Tweet]]',
		location = args_t.location,												-- why |location=?  tweets are online; there is no publication place
		['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
		}

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

	local author = ((cite_args_t.last1 and cite_args_t.first1) and cite_args_t.last1 .. ', ' .. cite_args_t.first1) or	-- concatenate |last= with |first= for |author-mask=
		(cite_args_t.last1 and cite_args_t.last1) or							-- only |last= for |author-mask=
		(cite_args_t.author1 and cite_args_t.author1:gsub('^%(%((.+)%)%)$', '%1'));	-- |author= or |author1= stripped of accept-as-written markup for |author-mask=

	if author and args_t.user then
		cite_args_t['author-mask'] = author .. ' [@' .. (args_t.user or '') .. ']'	-- concatenate <author> and |user= into |author-mask=
	elseif args_t.user then
		cite_args_t.author1 = '((' .. args_t.user .. '))';						-- just the user name for cs1|2 metadata
		cite_args_t['author-mask'] = '@' .. args_t.user;						-- make a mask for display
	else																		-- here when neither <author> nor |user=
		cite_args_t.author1 = nil;												-- so unset
	end

	frame.args = cite_args_t;													-- overwrite frame arguments
	local rendering = CiteWeb (frame);											-- render the template

---------- error messaging ----------
	if errors_t[2] then															-- errors_t[2] nil when no errors
		if rendering:find ('cs1-visible-error', 1, true) then					-- rendered {{cite web}} with errors will have this string
			errors_t[1] = errors_t[1]:gsub ('> <', '>; <');						-- insert semicolon to terminate cs1|2 error message string
		end

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

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

return p