Module:quick link

From Wiktionary, the free dictionary
Jump to navigation Jump to search

This module is experimental. It is intended to reduce the amount of Lua memory used by a template that has a lot of linking templates ({{l}}, {{l-self}}). It's used in {{Portuguese personal pronouns}} and {{ca-decl-ppron}}.

Portuguese personal pronouns (edit)
Number Person Nominative
(subject)
Accusative
(direct object)
Dative
(indirect object)
Prepositional Prepositional
with com
Non-declining
m f m f m and f m f m f m f
Singular First eu me mim comigo
Second tu te ti contigo você
o senhor a senhora
Third ele ela o
(lo, no)
a
(la, na)
lhe ele ela com ele com ela o mesmo a mesma
se si consigo
Plural First nós nos nós connosco (Portugal)
conosco (Brazil)
a gente
Second vós vos vós convosco, com vós vocês
os senhores as senhoras
Third eles elas os
(los, nos)
as
(las, nas)
lhes eles elas com eles com elas os mesmos as mesmas
se si consigo
Indefinite se si consigo

local export = {}

local function validate_lang(lang)
	return type(lang) == "table" and type(lang.getCode) == "function"
end

-- Entry names are processed with this function. Catalan has no entry-name
-- replacements, but apparently uses straight apostrophes in entry titles and
-- curly ones in displayed text.
local function curly_apostrophe_to_straight(str)
	return (str:gsub('’', "'"))
end

local function make_tag_func(lang, sc_code)
	if not (validate_lang(lang) and type(sc_code) == "string"
			and mw.loadData "Module:scripts/data"[sc_code]) then
		error("Invalid language object or script code.", 2)
	end
	
	local lang_code, lang_name = lang:getCode(), lang:getCanonicalName()
	
	return function (text)
		return '<span class="' .. sc_code .. '" lang="' .. lang_code .. '">'
			.. text .. '</span>'
	end
end

local function make_link_func(lang)
	if not validate_lang(lang) then
		error("Invalid language object.", 2)
	end
	
	local lang_code, lang_name = lang:getCode(), lang:getCanonicalName()
	
	return function (entry, text)
		return '[[' .. curly_apostrophe_to_straight(entry) .. '#' .. lang_name
			.. '|' .. (text or entry) .. ']]'
	end
end

local function make_link_and_tag_func(lang, sc_code)
	if not (validate_lang(lang) and type(sc_code) == "string"
			and mw.loadData "Module:scripts/data"[sc_code]) then
		error("Invalid language object or script code.", 2)
	end
	
	local lang_code, lang_name = lang:getCode(), lang:getCanonicalName()
	
	return function (entry, text)
		return '<span class="' .. sc_code .. '" lang="' .. lang_code .. '">[['
			.. curly_apostrophe_to_straight(entry) .. '#' .. lang_name .. '|'
			.. (text or entry) .. ']]</span>'
	end
end

-- Find grammatical terms such as "first person" and "plural" in part of the
-- Catalan personal pronouns table and link them.
local function link_terms_in_ca_table(text)
	local ordinals = { 'first', 'second', 'third' }
	
	text = text:gsub(
		'((%d)%l+ %l+)',
		function (whole_match, number)
			return '[[' .. ordinals[tonumber(number)] .. ' person|'
				.. whole_match:gsub(' ', '&nbsp;') .. ']]'
		end)
	
	text = text:gsub(
		'![^\n]+singular.-class="notes%-row"',
		function (table_interior)
			return table_interior:gsub(
				'%l+',
				function (word)
					local link
					if word == 'singular' or word == 'neuter' or word:find 'i[nv]e$'
							or word:find 'al$' then
						link = word
					elseif word == 'majestic' then
						link = 'majestic plural|majestic'
					end
					
					if link then
						return '[[' .. link .. ']]'
					end
				end)
		end)

	return text
end

function export.main(frame)
	local params = {
		title = {},
		lang = {},
		no_make_entry_name = { type = "boolean" },
	}
	
	local args = require "Module:parameters".process(frame.args, params)
	
	local title = args.title
	local lang = require "Module:languages".getByCode(args.lang)
		or require "Module:languages".err(args.lang, "lang")
	
	local content = frame:preprocess("{{" .. title .. "}}")
	
	local link_and_tag, link
	local sc_code = "Latn" -- Fix if language doesn't use Latin script!
	if args.no_make_entry_name or not lang._rawData.entry_name then
		link_and_tag = make_link_and_tag_func(lang, sc_code)
		link = make_link_func(lang)
	else
		local m_links = require "Module:links"
		local full_link = m_links.full_link
		local lang_link = m_links.language_link
		
		link_and_tag = function (entry, text)
			return full_link { term = entry, alt = text,
				lang = lang, sc = require "Module:scripts".getByCode(sc_code),
			}
		end
		
		link = function (entry, text)
			return lang_link { lang = lang, term = entry, alt = text }
		end
	end
	
	local tag = make_tag_func(lang, sc_code)
	
	linked_content = content:gsub(
		"%b[]",
		function (potential_link)
			if potential_link:sub(2, 2) == '[' and potential_link:sub(-2, -2) == ']' then
				local link_contents = potential_link:sub(3, -3) -- strip off outer brackets
				local target, text
				if link_contents:find "|" then
					target, text = link_contents:match "^([^|]+)|(.+)$"
				else
					target = link_contents
				end
				
				if target:find "^([^:]+):" or target:find "#" then
					return "[[" .. link_contents .. "]]"
				 -- There are nested wikilinks; they'd better be matching!
				elseif target:find('[[', 1, true) then
					return tag(target:gsub('%[%[(.-)%]%]', link))
				else
					return link_and_tag(target, text)
				end
			end
		end)
	
	if lang:getCode() == 'ca' then
		linked_content = link_terms_in_ca_table(linked_content)
	end
	
	return linked_content
end

return export