Module:Cite tweet: Difference between revisions

From Fanverse
Jump to navigation Jump to search
(Created page with "local TwitterSnowflake = require('Module:TwitterSnowflake') local err_msgs_t = { -- a sequence of snowflake date error messages; all must be terminated with a semicolon (;) ' <kbd>|date=</kbd> / <kbd>|number=</kbd> mismatch;', -- [1] ' <kbd>|date=</kbd> required;', -- [2] ' Invalid <kbd>|number=</kbd>;', -- [3] ' Missing or empty <kbd>|number=</kbd>;', -- [4] ' Missing or empty <kbd>|user=</kbd...")
 
No edit summary
 
Line 1: Line 1:
local TwitterSnowflake = require('Module:TwitterSnowflake')
local TwitterSnowflake = require('Module:TwitterSnowflake')


local err_msgs_t = { -- a sequence of snowflake date error messages; all must be terminated with a semicolon (;)
local err_msgs_t = {
' <kbd>&#124;date=</kbd> / <kbd>&#124;number=</kbd> mismatch;', -- [1]
' <kbd>&#124;date=</kbd> / <kbd>&#124;number=</kbd> mismatch;',
' <kbd>&#124;date=</kbd> required;', -- [2]
' <kbd>&#124;date=</kbd> required;',
' Invalid <kbd>&#124;number=</kbd>;', -- [3]
' Invalid <kbd>&#124;number=</kbd>;',
' Missing or empty <kbd>&#124;number=</kbd>;', -- [4]
' Missing or empty <kbd>&#124;number=</kbd>;',
' Missing or empty <kbd>&#124;user=</kbd>;' -- [5]
' Missing or empty <kbd>&#124;user=</kbd>;'
}
}
 
 
--[[--------------------------< 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 function suppress_url_in_title(frame, title)
local schemes = { -- schemes commonly found in tweets
local schemes = {
'https://',
'https://',
'http://',
'http://',
'ftp://',
'ftp://',
}
}


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


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




--[[--------------------------< D A T E _ N U M B E R _ U R L _ G E 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/'


extract |date= and |number= parameter values if present. Extract date from |number= and compare to |date=.
if not args_t.user then
table.insert(errors_t, err_msgs_t[5])
end


contruct |url= for {{cite web}} from the base url and |number= and |user=
if not args_t.date and not args_t.number then
err_msg_index = 4


returns nothing; adds date, number, url to <cite_args_t>; adds error message(s) to <errors_t>.
elseif args_t.number then


]]
if tonumber(args_t.number) then
cite_args_t.date =
args_t.date or
TwitterSnowflake.snowflakeToDate{
args = { id_str = args_t.number }
}


local function date_number_url_get (args_t, cite_args_t, errors_t)
cite_args_t.number = args_t.number
local err_msg_index;


cite_args_t.url = 'https://x.com/';         -- initialize with minimal base url because {{cite web}} requires |url=
if args_t.user then
if not args_t.user then
cite_args_t.url =
table.insert (errors_t, err_msgs_t[5]); -- error: missing or empty |user=
cite_args_t.url .. args_t.user .. '/status/' .. args_t.number
end
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
else
cite_args_t.date = args_t.date;
err_msg_index = 3
end
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
elseif args_t.date then
cite_args_t.url = cite_args_t.url .. args_t.user .. '/status/' .. args_t.number; -- construct |url= for {{cite web}}
cite_args_t.date = args_t.date
end
err_msg_index = 4
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


if err_msg_index then
if err_msg_index then
table.insert (errors_t, err_msgs_t[err_msg_index]); -- invalid number or missing necessary parameters so abandon
table.insert(errors_t, err_msgs_t[err_msg_index])
return;
return
end
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
err_msg_index = TwitterSnowflake.datecheck({
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
args = {
id_str = args_t.number or '',
date = args_t.date or '',
error1 = 1,
error2 = 2,
error3 = 3
}
})
 
 
if err_msg_index == 2 then
cite_args_t.date = nil
end
 
if err_msg_index then
table.insert(errors_t, err_msgs_t[err_msg_index])
end
end
table.insert (errors_t, err_msgs_t[err_msg_index]); -- add error message
end
end




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


construct parameter set for {{cite web}} from {{cite tweet}} parameters;  do some error checking
local function main(frame)


]]
local args_t = require('Module:Arguments').getArgs(frame)
 
local function main (frame)
local args_t = require ('Module:Arguments').getArgs (frame);


local cite_args_t = {
local cite_args_t = {
title = suppress_url_in_title (frame, args_t.title),
title = suppress_url_in_title(frame, args_t.title),
['script-title'] = suppress_url_in_title (frame, args_t['script-title']),
['script-title'] = suppress_url_in_title(frame, args_t['script-title']),
['trans-title'] = suppress_url_in_title (frame, args_t['trans-title']),
['trans-title'] = suppress_url_in_title(frame, args_t['trans-title']),
language = args_t.language,
language = args_t.language,
last1 = args_t.last1 or args_t.last,
last1 = args_t.last1 or args_t.last,
Line 116: Line 112:
via = args_t.link == 'no' and 'Twitter' or '[[Twitter]]',
via = args_t.link == 'no' and 'Twitter' or '[[Twitter]]',
type = args_t.link == 'no' and 'Tweet' or '[[Tweet (social media)|Tweet]]',
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
location = args_t.location,
['access-date'] = args_t['access-date'] or args_t.accessdate,
['access-date'] = args_t['access-date'] or args_t.accessdate,
['archive-date'] = args_t['archive-date'] or args_t.archivedate,
['archive-date'] = args_t['archive-date'] or args_t.archivedate,
Line 126: Line 122:
df = args_t.df,
df = args_t.df,
mode = args_t.mode
mode = args_t.mode
}
}
 
 
local errors_t = {
'<span class="cs1-visible-error citation-comment"> <kbd>{{[[Template:Cite tweet|Cite tweet]]}}</kbd>:'
}
 
 
date_number_url_get(args_t, cite_args_t, errors_t)
 


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
local author =
date_number_url_get (args_t, cite_args_t, errors_t); -- add |date=, |number=, |url= to <cite_args_t>
((cite_args_t.last1 and cite_args_t.first1) and cite_args_t.last1 .. ', ' .. cite_args_t.first1)
or (cite_args_t.last1 and cite_args_t.last1)
or (cite_args_t.author1 and cite_args_t.author1:gsub('^%(%((.+)%)%)$', '%1'))


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


local rendering = require ('Module:Citation/CS1')._citation (nil, cite_args_t, {CitationClass = 'web'});


---------- error messaging ----------
local rendering = require('Module:Citation/CS1')._citation(nil, cite_args_t, {CitationClass = 'web'})
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
if errors_t[2] then
 
if rendering:find('cs1-visible-error', 1, true) then
errors_t[1] = errors_t[1]:gsub('> <', '>; <')
end
end


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


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


--[[--------------------------< E X P O R T S >----------------------------------------------------------------
 
]]


return {
return {
main = main, -- entry points; {{#invoke:cite tweet|main|...}} is preferred
main = main,
[''] = main, -- but {{#invoke:cite tweet||...}} is also acceptable
[''] = main
}
}

Latest revision as of 04:10, 6 March 2026

Documentation for this module may be created at Module:Cite tweet/doc

local TwitterSnowflake = require('Module:TwitterSnowflake')

local err_msgs_t = {
	' <kbd>&#124;date=</kbd> / <kbd>&#124;number=</kbd> mismatch;',
	' <kbd>&#124;date=</kbd> required;',
	' Invalid <kbd>&#124;number=</kbd>;',
	' Missing or empty <kbd>&#124;number=</kbd>;',
	' Missing or empty <kbd>&#124;user=</kbd>;'
}


local function suppress_url_in_title(frame, title)
	local schemes = {
		'https://',
		'http://',
		'ftp://',
	}

	if title then
		for _, scheme in ipairs(schemes) do
			title = title:gsub(
				scheme,
				frame:callParserFunction('#tag', {'nowiki', scheme})
			)
		end
	end

	return title
end


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

	cite_args_t.url = 'https://x.com/'

	if not args_t.user then
		table.insert(errors_t, err_msgs_t[5])
	end

	if not args_t.date and not args_t.number then
		err_msg_index = 4

	elseif args_t.number then

		if tonumber(args_t.number) then
			cite_args_t.date =
				args_t.date or
				TwitterSnowflake.snowflakeToDate{
					args = { id_str = args_t.number }
				}

			cite_args_t.number = args_t.number

			if args_t.user then
				cite_args_t.url =
					cite_args_t.url .. args_t.user .. '/status/' .. args_t.number
			end

		else
			err_msg_index = 3
		end

	elseif args_t.date then
		cite_args_t.date = args_t.date
		err_msg_index = 4
	end


	if err_msg_index then
		table.insert(errors_t, err_msgs_t[err_msg_index])
		return
	end


	err_msg_index = TwitterSnowflake.datecheck({
		args = {
			id_str = args_t.number or '',
			date = args_t.date or '',
			error1 = 1,
			error2 = 2,
			error3 = 3
		}
	})


	if err_msg_index == 2 then
		cite_args_t.date = nil
	end

	if err_msg_index then
		table.insert(errors_t, err_msgs_t[err_msg_index])
	end
end



local function main(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,
		['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>:'
	}


	date_number_url_get(args_t, cite_args_t, errors_t)


	local author =
		((cite_args_t.last1 and cite_args_t.first1) and cite_args_t.last1 .. ', ' .. cite_args_t.first1)
		or (cite_args_t.last1 and cite_args_t.last1)
		or (cite_args_t.author1 and cite_args_t.author1:gsub('^%(%((.+)%)%)$', '%1'))


	if author and args_t.user then
		cite_args_t['author-mask'] = author .. ' [@' .. args_t.user .. ']'

	elseif args_t.user then
		cite_args_t.author1 = '((' .. args_t.user .. '))'
		cite_args_t['author-mask'] = '@' .. args_t.user

	else
		cite_args_t.author1 = nil
	end


	local rendering = require('Module:Citation/CS1')._citation(nil, cite_args_t, {CitationClass = 'web'})


	if errors_t[2] then

		if rendering:find('cs1-visible-error', 1, true) then
			errors_t[1] = errors_t[1]:gsub('> <', '>; <')
		end

		errors_t[#errors_t] =
			errors_t[#errors_t]:gsub(
				';$',
				' ([[Template:Cite_tweet#Error_detection|help]])'
			)

		table.insert(errors_t, '</span>')


		if mw.title.getCurrentTitle():inNamespace(0) then
			table.insert(errors_t, '[[Category:Cite tweet templates with errors]]')
		end


		rendering = rendering .. table.concat(errors_t)
	end

	return rendering
end



return {
	main = main,
	[''] = main
}