Module:interproject
Itsura
- This module lacks a documentation subpage. Please create it.
- Useful links: subpage list • links • transclusions • testcases • sandbox
local export = {}
local m_links = require("Module:links")
local m_params = require("Module:parameters")
local en_utilities_module = "Module:en-utilities"
local parse_interface_module = "Module:parse interface"
local parse_utilities_module = "Module:parse utilities"
local string_utilities_module = "Module:string utilities"
local table_module = "Module:table"
local wikimedia_languages_module = "Module:wikimedia languages"
local full_link = m_links.full_link
local concat = table.concat
local insert = table.insert
local boolean_param = {type = "boolean"}
local function track(page)
require("Module:debug/track")("interproject/" .. page)
end
local disambiguation_data
local function get_disambiguation_format_string(language)
if not disambiguation_data then
disambiguation_data = mw.loadData("Module:interproject/data/disambiguation")
end
return disambiguation_data[language] or "%s (disambiguation)"
end
-- Split an argument on comma, but not comma followed by whitespace, or backslash + comma, or comma inside of brackets.
local function split_on_comma(val)
if val:find(",") then
return require(parse_interface_module).split_on_comma(val)
else
return {val}
end
end
-- Join one or more items using commas, with "and" between the last two items.
local function join_on_comma(val)
if val[2] then
return require(table_module).serialCommaJoin(val)
else
return val[1]
end
end
-- Replace + with the pagename, but replace \+ with +.
local function substitute_plus(val, pagename)
if not val then
return val
end
if val:find("%+") then
val = val:gsub("%\\%+", "\1"):gsub("%+", require(string_utilities_module).replacement_escape(pagename)):
gsub("\1", "+")
end
return val
end
local function process_links(linkdata, prefix, name, wmlang, sc)
local links = {}
local iplinks = {}
for _, link in ipairs(linkdata) do
local this_wmlang = link.wmlang or wmlang
local this_prefix = prefix .. ":" .. (this_wmlang:getCode() == "en" and "" or this_wmlang:getCode() .. ":")
local lang = this_wmlang:getWiktionaryLanguage()
local ipalt = name .. " " .. (this_wmlang:getCode() == "en" and "" or "<sup>" .. this_wmlang:getCode() ..
"</sup>")
link.lang = lang
link.sc = sc
link.track_sc = true
link.no_nonstandard_sc_cat = true
link.tr = "-"
-- Strip diacritics according to Wiktionary language principles. This isn't done automatically with Wikipedia
-- links but seems a good idea to do. Prefix the link with a colon to override this. We try to separate the
-- fragment before doing this to avoid the term getting converted to an unsupported title, and don't do any
-- diacritic stripping on non-mainspace Wikipedia links.
if link.term:find("^:") then
link.term = link.term:sub(2)
elseif not link.term:find(":") then
-- Apply some Wikipedia-style transformations before calling stripDiacritics() to avoid problems with
-- the punctuation getting stripped.
local term, fragment = m_links.get_fragment(link.term:gsub("_", " "):gsub("%?", "%%3F"):gsub("!", "%%21"))
-- FIXME: This isn't sustainable and has to be removed.
local stripped_term = lang:stripDiacritics(term)
if stripped_term ~= term then
link.alt = link.alt or link.term
link.term = stripped_term .. (fragment and "#" .. fragment or "")
end
end
if link.fragment ~= nil then
link.alt = (link.alt or link.term) .. " § " .. link.fragment
end
if link.alt == link.term then
link.alt = nil
end
link.term = this_prefix .. link.term
insert(iplinks, "<span class=\"interProject\">[[" .. mw.ustring.gsub(link.term, "'''?", "") .. "|" .. ipalt ..
"]]</span>")
insert(links, full_link(link, "bold"))
end
return links, iplinks
end
local function parse_one_wikipedia_link(val, pagename, default_wmlang, link_prefix)
local origval = val
local rest, dab = val:match("^(.*)<(dab!?)>$")
val = rest or val
local langcode, rest = val:match("^([a-z][a-z-]+):(.*)$")
if rest and not rest:find("^ ") then
val = rest
else
langcode = nil
end
local wmlang
if langcode then
wmlang = require(wikimedia_languages_module).getByCodeWithFallback(langcode)
if not wmlang then
error(("Unrecogized Wikimedia or Wiktionary code '%s': %s"):format(langcode,
-- FIXME, move escape_wikicode() elsewhere
require(parse_utilities_module).escape_wikicode(origval)))
end
else
wmlang = default_wmlang
end
local link, label = val:match("^%[%[(.-)|(.*)%]%]$")
if not link then
link = val:match("^%[%[(.*)%]%]$")
end
link = link or val
local rest, fragment = link:match("^(.-)#(.*)$")
link = rest or link
if link == "" then
link = "+"
end
link = substitute_plus(link, pagename)
label = substitute_plus(label, pagename)
fragment = substitute_plus(fragment, pagename)
local user_specified_label = not not label
label = label or link
if label == "" then
-- implement pipe trick
rest = link:match("^(.+) %(.-%)$")
if rest then
label = rest
else
label = link:gsub(",.*$", "")
end
end
if dab == "dab" or dab == "dab!" then
link = get_disambiguation_format_string(wmlang:getCode()):format(link)
end
if dab == "dab!" then
label = get_disambiguation_format_string(wmlang:getCode()):format(label)
end
if user_specified_label and fragment then
link = link .. "#" .. fragment
fragment = nil
end
return {wmlang = wmlang, term = link_prefix .. link, alt = label, fragment = fragment}
end
local function parse_wikipedia_links(val, pagename, default_wmlang, link_prefix)
local raw_links = split_on_comma(val)
for i, raw_link in ipairs(raw_links) do
raw_links[i] = parse_one_wikipedia_link(raw_link, pagename, default_wmlang, link_prefix)
default_wmlang = raw_links[i].wmlang
end
return raw_links
end
-- FIXME: From [[Module:zh/templates]] implementation of old {{zh-wp}}; do we want something like this?
--local wp_data = {
-- ["zh"] = { "Written Standard Chinese<sup>[[w:Written vernacular Chinese|?]]</sup>", "zh" },
-- ["cdo"] = { "Eastern Min", "cdo" },
-- ["gan"] = { "Gan", "zh" },
-- ["hak"] = { "Hakka", "hak" },
-- ["lzh"] = { "Classical", "zh" },
-- ["nan"] = { "Southern Min", "nan" },
-- ["wuu"] = { "Wu", "zh" },
-- ["yue"] = { "Cantonese", "zh" },
--}
local function format_wikipedia_box(frame, linkdata, linktype, slim, sc)
local wmlangcode, multibox
for i, linkspec in ipairs(linkdata) do
if i == 1 then
wmlangcode = linkspec.wmlang:getCode()
elseif wmlangcode ~= linkspec.wmlang:getCode() then
multibox = true
break
end
end
if slim and not multibox then
for _, linkspec in ipairs(linkdata) do
if linktype == "category" then
linkspec.alt = "Category:" .. linkspec.alt
elseif linktype == "portal" then
linkspec.alt = "Portal:" .. linkspec.alt
end
end
end
if not linkdata[2] then
linktype = require(en_utilities_module).add_indefinite_article(linktype)
else
linktype = require(en_utilities_module).pluralize(linktype)
end
local links, iplinks = process_links(linkdata, "w", "Wikipedia", nil, sc)
local div_prefix = "<div class=\"interproject-box sister-wikipedia sister-project noprint floatright\">"
local template_extension = frame:extensionTag("templatestyles", "", {src="Module:interproject/style.css"})
if multibox then
local result = {
div_prefix ..
"<div style=\"float: left;\">[[File:Wikipedia-logo.png|32px|none|link=|alt=]]</div>" ..
"<div style=\"margin-left: 40px;\">[[Wikipedia]] has " .. linktype .. " on:<ul>"
}
for i, linkspec in ipairs(linkdata) do
local annotation = " <span style=\"font-size:80%\">(" .. linkspec.wmlang:getCanonicalName() .. ")</span>"
insert(result, "<li>" .. links[i] .. annotation .. "</li>")
end
insert(result, "</ul></div></div>" .. template_extension)
return concat(result)
elseif slim then
local wmlang = linkdata[1].wmlang
return
div_prefix ..
"<div style=\"float: left;\">[[File:Wikipedia-logo.png|14px|none| ]]</div>" ..
"<div style=\"margin-left: 15px;\">" ..
" " ..
join_on_comma(links, " at ") .. --TLCHANGE " and "
" sa " .. --TLCHANGE " on "
(wmlang:getCode() == "en" and "" or wmlang:getCanonicalName() .. " ") ..
"Wikipedia" ..
"</div></div>" .. template_extension
else
local wmlang = linkdata[1].wmlang
return
div_prefix ..
"<div style=\"float: left;\" class=\"interproject-box-logo\">[[File:Wikipedia-logo-v2.svg|x40px|none|link=|alt=]]</div>" ..
"<div style=\"margin-left: 60px;\">" ..
wmlang:getCanonicalName() .. " [[Wikipedia]] has " .. linktype .. " on:" ..
"<div style=\"margin-left: 10px;\">" .. join_on_comma(links) .. "</div>" ..
"</div>" .. concat(iplinks) .. "</div>" .. template_extension
end
end
function export.wikipedia_box(frame)
local params = {
[1] = true,
["cat"] = true,
["category"] = {alias_of = "cat"},
["i"] = boolean_param,
["lang"] = {type = "Wikimedia language", fallback = true, default = "en"},
["portal"] = true,
["sc"] = {type = "script"},
["pagename"] = true,
-- make old parameters throw an explanatory error; FIXME: eventually remove these.
[2] = {replaced_by = false, instead = "use a piped link in 1=, e.g. {{!((}}foo{{!}}bar{{))!}}"},
["mul"] = {replaced_by = false, instead = "use comma-separated items in 1="},
["mullabel"] = {replaced_by = false, instead = "use a piped link in 1=, e.g. {{!((}}foo{{!}}bar{{))!}}"},
["mulcat"] = {replaced_by = false, instead = "use comma-separated items in cat="},
["mulcatlabel"] = {replaced_by = false, instead = "use a piped link in cat=, e.g. {{!((}}foo{{!}}bar{{))!}}"},
["section"] = {replaced_by = false, instead = "use the syntax 'article#Section' in 1="},
}
local parargs = frame:getParent().args
local args = m_params.process(parargs, params)
local pagename = args.pagename or mw.loadData("Module:headword/data").pagename
local sc = args.sc
local linkdata, linktype
if parargs.lang then
-- Tracking for old use of lang= instead of a language prefix.
track("old-wp")
end
if (args[1] and 1 or 0) + (args.cat and 1 or 0) + (args.portal and 1 or 0) > 1 then
error("Can't specify more than one of 1=, cat= and portal=")
end
local rawval, link_prefix
if args.cat then
linktype = "category"
link_prefix = "Category:"
rawval = args.cat
elseif args.portal then
linktype = "portal"
link_prefix = "Portal:"
rawval = args.portal
else
linktype = "article"
link_prefix = ""
rawval = args[1] or ""
end
linkdata = parse_wikipedia_links(rawval, pagename, args.lang, link_prefix)
return format_wikipedia_box(frame, linkdata, linktype, frame.args.slim, sc)
end
function export.projectlink(frame, compat)
local required = {required = true}
local iparams = {
["prefix"] = required,
["name"] = required,
["image"] = required,
["requirelang"] = boolean_param,
["compat"] = boolean_param,
}
local iargs = m_params.process(frame.args, iparams)
compat = compat or iargs.compat
local lang_required = iargs.requirelang or false
local lang_param = compat and "lang" or 1
local term_param = compat and 1 or 2
local alt_param = compat and 2 or 3
local params = {
[lang_param] = {type = "Wikimedia language", method = "fallback", required = lang_required, default = "en"},
[term_param] = true,
[alt_param] = true,
["i"] = boolean_param,
["nodot"] = true,
["sc"] = {type = "script"},
["section"] = true
}
local args = m_params.process(frame:getParent().args, params)
local wmlang = args[lang_param]
local sc = args["sc"]
local term = args[term_param] or mw.loadData("Module:headword/data").pagename
local linkdata = {term = term, alt = args[alt_param], fragment = args["section"]}
if args["i"] then
local prefixed = "''"
if (iargs["prefix"] == "commons:Category") then
prefixed = "Category:" .. prefixed
end
if linkdata.alt then
linkdata.alt = prefixed .. linkdata.alt .. "''"
else
-- While it is true that the link module automatically removes italics from terms,
-- linkdata.term is used outside this module too (image link and "interProject" link)
linkdata.alt = prefixed .. linkdata.term .. "''"
end
end
local links, iplinks = process_links({linkdata}, iargs["prefix"], iargs["name"], wmlang, sc)
return
"[[Image:" .. iargs["image"] .. "|15px|link=" .. iargs["prefix"] .. ":" .. (wmlang:getCode() == "en" and "" or wmlang:getCode() .. ":") .. term .. "]] " ..
concat(links, " and ") ..
" on " ..
(wmlang:getCode() == "en" and "" or "the " .. wmlang:getCanonicalName() .. " ") ..
" " .. iargs["name"] .. (args["nodot"] and "" or ".") ..
concat(iplinks)
end
return export