Module:Wiktionary
Appearance
--[[
Implements {{Wiktionary}}.
]]
require ('strict');
local local_wiki_tag = mw.language.getContentLanguage().code; -- 'en' at enwiki
--[[--------------------------< E R R O R _ S I D E _ B O X >--------------------------------------------------
Return rendered error message text for {{sister project}} template which will then render the {{wiktionary}} side
box. This function does not call {{Sister project}}.
{{Sister project
|position={{{position|}}}
|project=wiktionary
|text={{#invoke:Wiktionary|main}} <!-- creates side box content -->
}}
]]
local function error_side_box (args_t, message, categories_t, frame)
return string.format ('<span style="color:#d33">%s: %s</span>%s', -- render the error message with categories
'<kbd>{{[[Template:Wiktionary|Wiktionary]]}}</kbd> error: ',
message,
table.concat (categories_t)
);
end
--[[--------------------------< S I D E _ B O X >--------------------------------------------------------------
Return rendered text for {{sister project}} template which will then render the {{wiktionary}} side box. This
function does not call {{Sister project}}.
{{Sister project
|position={{{position|}}}
|project=wiktionary
|text={{#invoke:Wiktionary|main}} <!-- creates side box content -->
}}
]]
local function side_box (args_t, items_t, categories_t, frame)
local links_t = {}; -- holds a list of interwiki-linked terms
for i, item_t in ipairs (items_t) do -- build an interwiki link to wiktionary
local title = item_t.term; -- wiktionary article title
if item_t.anchor then
title = title .. item_t.anchor; -- add a language-specific anchor if language tag or #anchor supplied in template call
end
links_t[i] = string.format ('[[wiktionary:%s%s|%s]]', -- create interwiki link for each individual term
(item_t.isSearch and "Special:Search/" or ""),
title, -- wiktionary article title + anchor
item_t.lang_text -- term wrapped in {{lang}}-provided markup for display
);
end
local join1 = ', '; -- create appropriate separators for the list of terms
local join2 = #items_t > 2 and ', or ' or ' or ';
return string.format ('Look up %s in Wiktionary, the free dictionary.%s', -- construct the text the goes inside the box
mw.text.listToText (links_t, join1, join2), -- concatenate the list of terms
table.concat (categories_t) -- add categories
);
end
--[[--------------------------< C A T E G O R Y _ A D D >------------------------------------------------------
returns nothing. Adds category wikilink to <categories_t> if the template is used in mainspace
TODO: categorize templates that have <term> without <tag>? On initial implementation of this module, that would
be every instance of the template so impractical at that time
]]
local added_cats_t = {};
local function category_add (category, categories_t)
if not mw.title.getCurrentTitle():inNamespace (0) then -- when not in mainspace
return; -- abandon
end
if added_cats_t[category] then -- when we've already added this category
return; -- abandon
end
local category_names_t = { -- a list of category names used by this module
['error'] = 'Wiktionary template errors',
['article title'] = 'Wiktionary template uses article title',
['anchor'] = 'Wiktionary template uses manual anchor',
-- ['no tag'] = 'Wiktionary template without language tag', -- see TODO above
}
table.insert (categories_t, table.concat ({ -- construct category wikilink
'[[Category:',
category_names_t[category],
']]'
}));
added_cats_t[category] = true; -- remember that we've added this category to <categories_t>
end
--[[--------------------------< S E T _ A N C H O R >----------------------------------------------------------
create a language-specific anchor (URI fragment) where the fragment is the wiktionary language name associated
with the language tag prefixed to the 'term'.
]]
local function set_anchor (item_t)
local wikt_lang_data = mw.loadData ('Module:Wikt-lang/data'); -- load wiktionary supported languages list
if not item_t.anchor then
if wikt_lang_data.redirects[item_t.tag] then
item_t.tag = wikt_lang_data.redirects[item_t.tag];
end
local data_t = wikt_lang_data.languages[item_t.tag]; -- primary wiktionary data source
local mw_lang_name; -- holds MediaWiki name for language tag
if not ({['mis'] = true, ['mul'] = true, ['zxx'] = true})[item_t.tag] then -- these are supported by MediaWiki but have no value here
mw_lang_name = mw.language.fetchLanguageName (item_t.tag, local_wiki_tag); -- get MediaWiki's language name as fallback
end
if data_t and data_t.name then -- if wiktionary has name for language tag <item.tag>; not present for default tag 'und'
item_t.anchor = mw.uri.anchorEncode ('#' .. data_t.name); -- make an encoded anchor from the wiktionary language name so that it matches the language tag from the template call
elseif mw_lang_name and (mw_lang_name ~= item_t.tag) and ('und' ~= item_t.tag) then -- fetchLanguageName() returns tag if tag not supported
item_t.anchor = mw.uri.anchorEncode ('#' .. mw_lang_name); -- make an encoded anchor from the MediaWiki language name so that it matches the language tag from the template call
elseif 'und' ~= item_t.tag then -- when neither wiktionary nor MediaWiki have a definition for <item_t.tag> ('und' excepted)
item_t.error = 'language tag "' .. item_t.tag .. '" is not known to wiktionary';
return; -- abandon
end
end
if '' == item_t.anchor then -- if anchor is set to empty string
item_t.anchor = nil; -- unset so we don't create a link with trailing '#' fragment marker
end
end
--[[--------------------------< M A I N >----------------------------------------------------------------------
Return wikitext to display {{wiktionary}} box.
]]
local function main (frame)
local args_t = require ('Module:Arguments').getArgs (frame);
local items_t = {};
local categories_t = {};
local lang_mod = require ('Module:lang'); -- for direct access to the functions in Module:Lang
local lang_text; -- term and markup returned from Module:Lang.lang
for _, arg in ipairs (args_t) do
arg = mw.text.trim (arg);
if arg ~= '' then
local tag, term, anchor;
if arg:match ('^%a%a%a?:.+') then -- does this arg have language tag prefix and a term?
tag, term = arg:match ('^(%a%a%a?):(.*)'); -- yep, then extract them
else
term = arg; -- nope, just a term
end
if term:match ('.+#.+') then -- does <term> hav an anchor (URL fragment)?
term, anchor = term:match ('(.+)(#.+)'); -- split the 'term#ancor' into <term> and <anchor>
category_add ('anchor', categories_t); -- add a category
end
table.insert (items_t, {tag = tag or 'und', term = term, anchor = anchor});
end
end
if items_t[1] then
for _, item_t in ipairs (items_t) do
local italic = (item_t.tag == local_wiki_tag) and 'yes' or nil; -- local language same as language tag, italicize per words-as-words
lang_text = lang_mod._lang ({item_t.tag, item_t.term, cat = 'no', italic = italic}); -- let {{lang}} control italics
if lang_text:match ('color: *#d33') or lang_text:match ('color: *#33aa33') then
category_add ('error', categories_t); -- add a category
return table.concat ({
error_side_box (args_t, 'language tag "' .. item_t.tag .. '" is not known to wikipedia', categories_t, frame),
(mw.title.getCurrentTitle():inNamespace (0) and '[[Category:Wiktionary template errors]]') or ''
}); -- abandon with error message
end
item_t.lang_text = lang_text;
set_anchor (item_t);
if item_t.error then
category_add ('error', categories_t); -- add a category
return table.concat ({ -- abandon with error message
error_side_box (args_t, item_t.error, categories_t, frame), -- tag not known to wiktionary
(mw.title.getCurrentTitle():inNamespace (0) and '[[Category:Wiktionary template errors]]') or ''
}); -- abandon with error message
end
end
else -- no terms supplied in template call so use article title
local title = mw.ustring.lower(mw.title.getCurrentTitle().subpageText); -- get the title; TODO: should we be setting page title to lowercase?
lang_text = lang_mod._lang ({local_wiki_tag, title, cat = 'no', italic = 'yes'}); -- for consistency use {{lang}} for article title; italic per words-as-words
items_t[1] = {term = title, lang_text = lang_text, isSearch = true }; -- don't break side box
category_add ('article title', categories_t); -- add a category
end
return side_box (args_t, items_t, categories_t, frame);
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
main = main
}