Module:Annotated link: Difference between revisions

Content deleted Content added
exclude single word descriptions where that word is part of the link name e.g. Knaster–Tarski theorem – Theorem
disable wikidata short descriptions, per RFC and multiple talk page discussions. Please report any bugs on the template talk page
 
(2 intermediate revisions by 2 users not shown)
Line 1:
 
local function pipedLink( name, display ) return '[[:' .. name .. '|' .. display .. ']]' end
 
local function isEmpty( value ) return value == nil or value == '' end
 
local function notEmpty( value ) return not isEmpty( value ) end
 
-- Unescape functionality grabbed from https://stackoverflow.com/a/14899740/1832568
local function unescape( str )
str = string.gsub( str, '&#(%d+);', string.char )
str = string.gsub( str, '&#x(%d+);', function( d ) return string.char( tonumber( d, 16 ) ) end )
return str
end
 
local function hashDelimitedList( list_string ) return mw.text.gsplit( unescape( list_string ), '%s*#%s*' ) end
 
local function alarmingMessage( message )
return '<span style="color:#d33">[[Module:Annotated link]] ' .. message .. '.</span>'..
.. '[[Category:Pages displaying alarming messages about Module:Annotated link]]'
end
 
local function optionallyVisibleCategory( class, category )
return '<span style="display:none" class="' .. class .. '">' .. category ..
'</span>[[Category:' .. category .. ' via Module:Annotated link]]'
end
 
local function handleFirstLetterCase( short_description, case )
return mw.ustring.gsub( short_description, '^([^%d])', function( first_char )
if case == 'upper' then
return mw.ustring.upper( first_char )
end
return mw.ustring.lower( first_char ) end
)
end
 
local mLang = require( 'Module:Lang' )
local function langify( args )
local lang = args.lang
local text = args.text
if isEmpty( lang ) or lang == 'en' then
return text
end
return mLang._lang {
lang,
Line 47 ⟶ 52:
end
 
local function formatResult( result, dash, description, prefix_parentheses)
if notEmpty( description ) then return result .. dash .. ' ' .. description end
if prefix_parentheses then
local startIdx = description:find("%(")
if startIdx then
local beforeParens = description:sub(1, startIdx - 2)
local insideParens = description:sub(startIdx, -1)
return result..' '..insideParens..dash..' '..beforeParens
end
end
return result..dash..' '..description
end
return result
end
 
local function annotatedLink( args )
local name = args.name
if isEmpty( name ) then
return alarmingMessage( 'requires a page name (including namespace)' )
end
-- In order to handle an attempt to annotate a template link
-- already formatted with the likes of {{tl|<template name>}};
-- unescape name to make sense of braces in lua patern matching.
name = unescape( name )
if name:match( '^{%b{}}$' ) then
-- The possibility to extract useful data exists here: e.g. {{tl*|Template}}.
return alarmingMessage(
'requires only a page name (including namespace) without markup. ' ..
'If an attempt is being made to annotate a link to a template, '..
'provide only the template name with namespace e.g. "Template:Example"' )
end
-- If a literal link was provided as name;
-- extract the content and apply it to name and display as appropriate.
local wikilink = mw.ustring.match( name, '^%[%[%s*:*%s*(.-)%s*%]%]$' )
if wikilink then
local link_name, link_display = unpack( mw.text.split( wikilink, '%s*|%s*' ) )
if link_name then
name = link_name
end
if link_display and isEmpty( args.display ) then
args.display = link_display
end
end
Line 77 ⟶ 102:
local result
local is_template = name:match( '^Template:(.+)$' )
local template_link = args.template_link
if is_template and template_link ~= 'no' then
result = '{{' .. pipedLink( name, is_template ) .. '}}'
if template_link == 'code' then
result = '<code>' .. result .. '</code>'
end
else
local display = args.display
if isEmpty( display ) then
display = name
end
result = langify( {
result = langify( {
lang = args.link_lang,
text = pipedLink( name, display ),
italic = args.link_lang_italic,
nocat = args.link_lang_nocat,
Line 96 ⟶ 122:
cat = args.link_lang_cat,
rtl = args.link_lang_rtl
} )
if notEmpty( args.quote ) then
result = '"' .. result .. '"'
end
local abbr = args.abbr
if notEmpty( abbr ) then
result = result .. ' (<abbr'
local abbr_title = args.abbr_title
if notEmpty( abbr_title ) then
result = result .. ' title="' .. abbr_title .. '"' end
end
result = result .. '>' .. abbr .. '</abbr>)'
end
end
if isEmpty( result ) then
return alarmingMessage( 'could not create a link for "' .. name .. '"' )
end
local aka = args.aka
if notEmpty( aka ) then
result = result .. ', also known as ' .. langify( {
lang = args.aka_lang,
text = aka,
Line 121 ⟶ 153:
cat = args.aka_lang_cat,
rtl = args.aka_lang_rtl
} )
end
local wedge = args.wedge
if notEmpty( wedge ) then
result = result .. ', ' .. langify( {
lang = args.wedge_lang,
text = wedge,
Line 134 ⟶ 166:
cat = args.wedge_lang_cat,
rtl = args.wedge_lang_rtl
} )
end
-- Exclude wikidata fallback for any specified list of link titles,
-- unless explicity instructed that it's okay.
local not_wikidata_for_links_starting_with = args.not_wikidata_for_links_starting_with
if isEmpty( args.wikidata ) and notEmpty( not_wikidata_for_links_starting_with ) then
for only_explicit in hashDelimitedList( not_wikidata_for_links_starting_with ) do
if name:match( '^' .. only_explicit ) then
args.only = 'explicit'
break end
end
end
end
-- Get the short description from Module:GetShortDescription.
local short_description = require( 'Module:GetShortDescription' ).main( {
none_is_valid = args.none_is_valid,
none_is_nil = args.none_is_nil,
lang_italic = args.desc_lang_italic,
lang_nocat = args.desc_lang_nocat,
Line 159 ⟶ 194:
only = args.only,
name = name
} )
local dash = args.dash
if isEmpty( dash ) then
dash = '&nbsp;–'
end
 
local fallback = args.fallback
 
if isEmpty( short_description ) or short_description.redlink then
return formatResult( result, dash, fallback, args.prefix_parentheses)
end
if short_description.alarm then
return short_description.alarm
end
local maintenance = ''
if short_description.redirected then
maintenance = optionallyVisibleCategory(
'category-annotation-with-redirected-description',
'Pages displaying short descriptions of redirect targets' )
end
Line 179 ⟶ 222:
if short_description.wikidata then
-- if short_description.fellback then
-- fellback = true
-- maintenance = maintenance .. optionallyVisibleCategory(
-- 'category-wikidata-fallback-annotation',
-- 'Pages displaying wikidata descriptions as a fallback' )
-- end
-- short_description = short_description.wikidata
-- Filter against likely rubbish wikidata descriptions.
-- local not_wikidata_descriptions_including = args.not_wikidata_descriptions_including
-- if notEmpty( not_wikidata_descriptions_including ) then
-- Case insentive matching.
-- local lower_case_short_description = short_description:lower()
-- for exclusion in hashDelimitedList( not_wikidata_descriptions_including:lower() ) do
-- if lower_case_short_description:match( exclusion ) then
short_description = '' break end
-- end break
-- end
-- end
-- end
if isEmpty( short_description ) then return formatResult( result, dash, fallback ) end
return formatResult(result, dash, fallback, args.prefix_parentheses)
end
else
if isEmpty( short_description ) then return formatResult( result, dash, fallback ) end
else short_description = short_description.explicit
end
local lower_case_name = name:lower()
if notEmpty( short_description ) and not short_description:match( ' ' ) then
-- Filter against likely rubbish single word descriptions.
local lower_case_short_description = short_description:lower()
local not_single_word = args.not_single_word
if notEmpty( not_single_word ) then
-- Case insentive matching.
for single_word in hashDelimitedList( not_single_word:lower() ) do
if single_word == lower_case_short_description then
short_description = ''
break end
end
end
end
if isEmpty( short_description ) or lower_case_name:match( lower_case_short_description ) then
return formatResult( result, dash, fallback, args.prefix_parentheses)
end
if isEmpty( args.space_cat ) then
maintenance = maintenance .. optionallyVisibleCategory(
'category-spaceless-annotation',
'Pages displaying short descriptions with no spaces' )
end
end
if lower_case_name == short_description:lower() then
if fellback then
return formatResult( result, dash, fallback, args.prefix_parentheses)
end
maintenance = maintenance .. optionallyVisibleCategory(
'category-annotation-matches-name',
'Pages displaying short descriptions matching their page name' )
end
Line 226 ⟶ 289:
local desc_first_letter_case = args.desc_first_letter_case
if desc_first_letter_case == 'upper' or desc_first_letter_case == 'lower' then
short_description = handleFirstLetterCase( short_description, desc_first_letter_case )
end
return formatResult( result, dash, ( short_description or fallback ) .. maintenance, args.prefix_parentheses)
end
 
local p = {}
 
function p.main( frame )
local args = require( 'Module:Arguments' ).getArgs( frame )
if isEmpty( args ) then
return alarmingMessage( 'could not getArgs' ) end -- This really would be alarming.
end
return annotatedLink( args )
end