ข้ามไปเนื้อหา

มอดูล:Annotated link

จากวิกิพีเดีย สารานุกรมเสรี
Documentation icon คู่มือการใช้งานมอดูล[ดู] [แก้] [ประวัติ] [ล้างแคช]

Usage[แก้]

{{#invoke:Annotated link|main

  |name= |display= |quote= |abbr= |abbr_title= |template_link= |aka= |wedge= |dash= |desc_first_letter_case= |space_cat= |prefix_parentheses=

  |link_lang= |link_lang_italic= |link_lang_nocat= |link_lang_size= |link_lang_cat= |link_lang_rtl=

  |aka_lang= |aka_lang_italic= |aka_lang_nocat= |aka_lang_size= |aka_lang_cat= |aka_lang_rtl=

  |wedge_lang= |wedge_lang_italic= |wedge_lang_nocat= |wedge_lang_size= |wedge_lang_cat= |wedge_lang_rtl=

  |only= |prefer= |fallback=

  |desc_lang_italic= |desc_lang_nocat= |desc_lang_size= |desc_lang_cat= |desc_lang_rtl= |desc_lang_no=

}}

name[แก้]

By providing only the required page name (including namespace), the module will use Module:GetShortDescription to look for an explicit {{short description}} in that page, but if not found, will try to fetch the wikidata description. This is equivalent to stating |prefer=explicit; see #prefer (below). If a description is found, it will be appended to a link created for the named page in the style expected for the likes of MOS:SEEALSO. If no description is found, the link will be created but no extra information will be appended – unless the extensive following parameters are employed.

Any foreign language (i.e. not en) text supplied to this module or retrieved by Module:GetShortDescription may be appropriately formatted, in accordance with MOS:OTHERLANG, via the parameters for Module:Lang; see #Foreign language text (below).

As this module is responsible for the use of all features of Module:GetShortDescription; all the parameters for that module are available through this module; see #Module:GetShortDescription parameters (below).

Markup: {{#invoke:Annotated link|main |name=The Partisan }}
Result: The Partisan

This and the following example song titles should be double quoted per MOS:POPMUSIC; that will be handled by #quote (below), and you will see the parameters in use where appropriate from here on.

display[แก้]

Providing a value for |display= will format the piped link with a display string:

Markup: {{#invoke:Annotated link|main |name=Jump (Every Little Thing song) |display=Jump |quote=yes }}
Result: "Jump"

quote[แก้]

Stating |quote=yes will double quote the link:

Markup: {{#invoke:Annotated link|main |name=The Partisan |quote=yes }}
Result: "The Partisan"
Markup: {{#invoke:Annotated link|main |name=Jump (Every Little Thing song) |display=Jump |quote=yes }}
Result: "Jump"

abbr[แก้]

Providing a value for |abbr= will append the link with the provided parenthesized abbreviation with <abbr>...</abbr> semantic markup:

Markup: {{#invoke:Annotated link|main |name=Confédération Mondiale des Activités Subaquatiques |display=World Underwater Federation |abbr=CMAS }}
Result: World Underwater Federation (CMAS)

An optional |abbr_title= may be provided:

Markup: {{#invoke:Annotated link|main |name=Confédération Mondiale des Activités Subaquatiques |display=World Underwater Federation |abbr=CMAS |abbr_title=Confédération Mondiale des Activités Subaquatiques }}
Result: World Underwater Federation (CMAS)

template_link[แก้]

If the linked page is in the Template namespace; the link will be formatted in the manner expected by {{template link}}:

Markup: {{#invoke:Annotated link|main |name=Template:Annotated link }}
Result: {{Annotated link}} – หน้าแม่แบบวิกิมีเดีย

Stating |template_link=code will display the link formatted with <code>...</code>:

Markup: {{#invoke:Annotated link|main |name=Template:Annotated link |template_link=code }}
Result: {{Annotated link}} – หน้าแม่แบบวิกิมีเดีย

The previously described parameters – |display=, |quote=, |abbr= and |abbr_title= – and all foreign language link options under |link_lang= (see #Foreign language text (below)) will be ignored if the link is in the Template namespace.

Stating |template_link=no will disable this special link formatting and the ignorance of the above-mentioned parameters:

Markup: {{#invoke:Annotated link|main |name=Template:Annotated link |template_link=no |display=Annotated link }}
Result: Annotated link – หน้าแม่แบบวิกิมีเดีย

aka[แก้]

Providing a value for |aka= will append the link (and |abbr= if provided) with a useful alternative name:

Markup: {{#invoke:Annotated link|main |name=The Partisan |quote=yes |aka=La Complainte du partisan }}
Result: "The Partisan", also known as La Complainte du partisan
Markup: {{#invoke:Annotated link|main |name=Confédération Mondiale des Activités Subaquatiques |display=World Underwater Federation |abbr=CMAS |aka=Confédération Mondiale des Activités Subaquatiques }}
Result: World Underwater Federation (CMAS), also known as Confédération Mondiale des Activités Subaquatiques

These and some following examples contain foreign language text that, per MOS:OTHERLANG, should be appropriately displayed and declared via HTML markup as being of that language; this will be handled by various parameters; see #Foreign language text (below) for full details, and you will see the parameters in use where appropriate from here on.

wedge[แก้]

Providing a value for |wedge= will append the link (and |abbr= and |aka= in that order if either or both is provided) with any extra details felt suitable:

Markup: {{#invoke:Annotated link|main |name=The Partisan |quote=yes |wedge=from the album ''[[Songs from a Room]]'' |aka=La Complainte du partisan |aka_lang=fr }}
Result: "The Partisan", also known as La Complainte du partisan, from the album Songs from a Room

For complementary foreign language params; see #Foreign language text (below).

dash[แก้]

For list consistency, per MOS:LISTFORMAT; by providing a value for |dash=; the dash between the short description and the preceding text may be exchanged for a suitable alternative:

Markup: {{#invoke:Annotated link|main |name=The Partisan |quote=yes |dash=, }}
Result: "The Partisan"

desc_first_letter_case[แก้]

Short descriptions on en Wikipedia should be formatted with an uppercase first letter, but the typical application of this module will require the first character to be lowercase. By default; this module will ensure all the short descriptions retrieved by Module:GetShortDescription are transformed to start with a lowercase first letter, but this may be overridden if required using |desc_first_letter_case=upper or |desc_first_letter_case=lower.

prefix_parentheses[แก้]

Sometimes date ranges in short descriptions are included in a suffixed parenthetical, per WP:SDDATES e.g. for Jimmy Wales: "Co-founder of Wikipedia (born 1966)".

However when listing people in disambiguation pages per MOS:DABPEOPLE, birth and death dates in parentheticals should precede the comma, as in "Jimmy Wales (born 1966), co-founder of Wikipedia".

If the optional parameter |prefix_parentheses=y is provided, this behavior will be performed, so any suffixed parenthetical text will be moved to before the dash (or comma) separator.

Note that current consensus is to not use {{annotated link}} for disambiguation pages; see Template:Annotated link/doc#Usage.

space_cat[แก้]

In the event that a short description with no spaces is retrieved and displayed; pages transcluding the annotation will be added to Category:Pages displaying short descriptions with no spaces via Module:Annotated link for interested editors to monitor for potential issues. Potential issues might include: garbage keyboard mashings, a typo of "none" while attempting to disable an explicit {{short description}} or some misunderstanding on the part of an editor placing one.

If the transclusion on a page in this category is checked and it is determined to be okay; stating a value for |space_cat= in the invocation will disable the categorisation. This should only be done on a case by cases basis, as opposed to as a default, or no potentially inappropriate annotations will be categorised; i.e. allow this parameter to be set in individual transclusions of templates which invoke this module, like {{annotated link}}, rather than in the template code.

Module:GetShortDescription parameters[แก้]

The value provided with |name= is passed through this module to Module:GetShortDescription where it is also required; the expectations of this module are described in #name (above). Module:GetShortDescription uses the value to find a {{short description}} in the named page, or various alternatives depending on parameter values.

only[แก้]

Providing a value for |only= will limit the search to being only for the stated description. If no description is found, the result will be an empty string, unless a fallback is provided; see #fallback (below).

Stating |only=explicit will limit the search to only short descriptions set by use of {{short description}} on the searched page.
Stating |only=wikidata will limit the search to only wikidata descriptions.

prefer[แก้]

Providing a value for |prefer= will initiate the search for the stated description, but try for the alternative if none is found. If no description is found, the result will be an empty string, unless a fallback is provided; see #fallback (below).

State |prefer=explicit to use the explicit short description if available, or try for the wikidata description if not.
State |prefer=wikidata to use the wikidata description if available, or try for an explicit short description if not.

fallback[แก้]

If a |fallback= value is provided, and no description is found by the expressed route, the appended description will be the stated fallback value.

Foreign language text[แก้]

Module:GetShortDescription may return a foreign language (i.e. not en) wikidata description; editor discretion determines if that should be displayed. If it is displayed; it will be in accordance with MOS:OTHERLANG, by Module:Lang (the module powering {{lang}}). The appropriate language code will be set automatically, but all other parameters of {{lang}} are available to affect the formatting of the returned description:

Use |lang_italic=, |lang_nocat=, |lang_size=, |lang_cat= and |lang_rtl=; see lang's documentation for details.

If the editor determines that {{lang}} formatting is not appropriate; it may be disabled with |lang_no=yes. The following {{lang}} formatting parameters are optional, so there is no off-switch required.

link_lang[แก้]

If the link text is of a foreign language (again; editor discretion); control the formatting with: |link_lang=<language code>, |link_lang_italic=, |link_lang_nocat=, |link_lang_size=, |link_lang_cat= and |link_lang_rtl=

aka_lang[แก้]

If the |aka= text is of a foreign language (again; editor discretion); control the formatting with: |aka_lang=<language code>, |aka_lang_italic=, |aka_lang_nocat=, |aka_lang_size=, |aka_lang_cat=, |aka_lang_rtl=

wedge_lang[แก้]

If the |wedge= text is of a foreign language (again; editor discretion); control the formatting with: |wedge_lang=<language code>, |wedge_lang_italic=, |wedge_lang_nocat=, |wedge_lang_size=, |wedge_lang_cat=, |wedge_lang_rtl=

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,
		text,
		italic = args.italic,
		nocat = args.nocat,
		size = args.size,
		cat = args.cat,
		rtl = args.rtl
	}
end

local function formatResult(result, dash, description, prefix_parentheses)
	if notEmpty(description) then
		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
	
	-- Prepare to concatenate.
	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({
			lang = args.link_lang,
			text = pipedLink(name, display),
			italic = args.link_lang_italic,
			nocat = args.link_lang_nocat,
			size = args.link_lang_size,
			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
			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,
			italic = args.aka_lang_italic,
			nocat = args.aka_lang_nocat,
			size = args.aka_lang_size,
			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,
			italic = args.wedge_lang_italic,
			nocat = args.wedge_lang_nocat,
			size = args.wedge_lang_size,
			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
	
	-- 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,
		lang_size = args.desc_lang_size,
		lang_cat = args.desc_lang_cat,
		lang_rtl = args.desc_lang_rtl,
		lang_no = args.desc_lang_no,
		prefer = args.prefer,
		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
	
	local fellback
	
	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
		end
		if isEmpty(short_description) then
			return formatResult(result, dash, fallback, args.prefix_parentheses)
		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
		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
	
-- Short descriptions on en Wikipedia should be formatted with an uppercase first letter, but
-- the typical application of this module will require the first character to be lowercase, but
-- some descriptions may start with proper names and should start with an uppercase letter even if used in an annotaion.
-- By default; this module will not affect the first letter case of descriptions retrieved by Module:GetShortDescription, but
-- the first letter case may be transformed explicitly if required.
	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') -- This really would be alarming.
	end
	return annotatedLink(args)
end

return p