Jump to content

Module:GetShortDescription

Permanently protected module
From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Fred Gandt (talk | contribs) at 09:50, 31 January 2023 (drumroll....). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.

local p = {}

local mLang = require( 'Module:Lang' )

local function pipedLink( name ) return '[[:' .. name ..  '|' .. name .. ']]' end

local function isEmpty( value ) return value == nil or value == '' end

local function notEmpty( value ) return not isEmpty( value ) end

local function alarmingMessage( message, nocat )
	message = '<span style="color:#d33">[[Module:GetShortDescription]] ' .. message .. '.</span>'
	if not nocat then message = message .. '[[Category:Pages displaying alarming messages about Module:GetShortDescription]]' end
	return message
end

-- Grammatically reasonable concatenation of possible issues into one message per problematic link target.
local function previewWarning( name, counters, probable_short_descriptions )
	local message = ''
	for i, params in ipairs( counters.params ) do
		if params > 3 then message = message .. ' with extraneous parameters' break end
	end
	if probable_short_descriptions > 1 then
		message = message .. ', declaring ' .. probable_short_descriptions .. ' short descriptions'
	end
	if counters.templates > 1 or notEmpty( message ) then
		message = 'has ' .. counters.templates .. ' {{tlx|short description}}' .. message
	end
	if notEmpty( message ) then
		local foo = alarmingMessage( 'has detected that ' .. pipedLink( name ) .. ' ' .. message, true )
		mw.log( foo )
		mw.addWarning( foo )
	end
end

local function getWikidataDescription( name, lang )
	local wikidata_id = mw.wikibase.getEntityIdForTitle( name )
	if isEmpty( wikidata_id ) then return nil end
	local wikidata_description, wikidata_description_lang = mw.wikibase.getDescriptionWithLang( wikidata_id )
	if isEmpty( wikidata_description ) then return nil end
	if notEmpty( lang.no ) or wikidata_description_lang == 'en' then return wikidata_description end
	if isEmpty( wikidata_description_lang ) then return nil end
	return  mLang._lang {
		wikidata_description_lang,
		wikidata_description,
		italic = lang.italic,
		nocat = lang.nocat,
		size = lang.size,
		cat = lang.cat,
		rtl = lang.rtl
	}
end

local function getExplicitDescription( name )
	local page_content = mw.title.new( name ):getContent()
	if isEmpty( page_content ) then return alarmingMessage( 'could not getContent of ' .. pipedLink( name ) ) end
	local contents_of_all_short_description_templates = {}
	-- Because there could be any number of short description templates, and not all where there should be; get all the templates.
	for template in mw.ustring.gmatch( page_content, '{%b{}}' ) do
		local short_description_content = mw.ustring.match( template, '^{{%s*[Ss]hort description%s*|%s*(.-)%s*}}' )
		if notEmpty( short_description_content ) then
			-- Collect the contents of short description templates.
			contents_of_all_short_description_templates[ #contents_of_all_short_description_templates+1 ] = short_description_content
		end
		-- An opportunity for efficiency gain exists - to break if another type of template is found e.g. citation templates,
		-- but on an appallingly formatted page, a short description template down by the categories would likely be missed.
	end
	if #contents_of_all_short_description_templates < 1 then return nil end
	-- Start gethering numbers of things.
	local counters = { templates = #contents_of_all_short_description_templates, params = {} }
	local possible_short_descriptions = {}
	for tci, short_description_template_contents in ipairs( contents_of_all_short_description_templates ) do
		possible_short_descriptions[ tci ] = {}
		-- Split the contents at pipes and trim.
		local short_description_template_params = mw.text.split( short_description_template_contents, '%s*|%s*' )
		counters.params[ tci ] = #short_description_template_params
		for i, param in ipairs( short_description_template_params ) do
			
			-- pleb overload
			
			if param == 'noreplace' or mw.ustring.match( param, '^2%s*=%s*noreplace$' ) then
				possible_short_descriptions[ tci ].noreplace = true
			else
				local has_equals = param:match( '=' )
				if not has_equals or param:match( '^1' ) then
					if has_equals then param = mw.ustring.gsub( param, '^1%s*=%s*', '' ) end
					if not param:match( '^[Nn]one$' ) then
						possible_short_descriptions[ tci ].description = param
					end
				end
			end
			
			
		end
	end
	
	-- at this point we could have noreplace-ing entries with no descriptions
	
	-- if the only descriptions we have are 'none' then return nil
	
	local probable_short_descriptions = {}
	for i, possible_short_description in ipairs( possible_short_descriptions ) do
		if possible_short_description.description then
			-- If a description is 'noreplace'-ing; demote it.
			if possible_short_description.noreplace and #possible_short_descriptions > 1 then
				-- But don't demote it if it's already at the bottom.
				if i > 1 then table.insert( probable_short_descriptions, #probable_short_descriptions, possible_short_description )
				else probable_short_descriptions[ #probable_short_descriptions+1 ] = possible_short_description end
			else
				probable_short_descriptions[ #probable_short_descriptions+1 ] = possible_short_description
			end
		end
	end
	
	mw.logObject( probable_short_descriptions )
	
	-- Let previewWarning() work out if these numbers are bad.
	previewWarning( name, counters, #probable_short_descriptions )
	
	if #probable_short_descriptions >= 1 then
		local foo = probable_short_descriptions[ #probable_short_descriptions ].description
		mw.log( foo )
		return foo
	end
	return nil
end

local function getShortDescription( args )
	local name = args.name
	if isEmpty( name ) then return alarmingMessage( 'requires a page name (including namespace)' ) end
	local result
	local only = args.only
	local prefer = args.prefer
	if isEmpty( prefer ) then prefer = 'explicit' end
	local lang = {
		italic = args.lang_italic,
		nocat = args.lang_nocat,
		size = args.lang_size,
		cat = args.lang_cat,
		rtl = args.lang_rtl,
		no = args.lang_no
	}
	if only == 'explicit' then result = getExplicitDescription( name )
	elseif only == 'wikidata' then result = getWikidataDescription( name, lang )
	elseif prefer == 'explicit' then result = getExplicitDescription( name ) or getWikidataDescription( name, lang )
	elseif prefer == 'wikidata' then result = getWikidataDescription( name, lang ) or getExplicitDescription( name )
	end
	return result or args.fallback
end

function p.main( frame ) return getShortDescription( frame.args ) or '' end

function p.test( frame )
	local foo = '12=derp'
	mw.log( mw.ustring.match( foo, '^1%s*=' ) )
end

return p