Module:WP
| This module depends on the following other modules: |
Implements {{WP}}
require('strict');
local getArgs = require ('Module:Arguments').getArgs;
local mRedirect = require ('Module:Redirect')
local namespaces = { -- includes namespace aliases - these are case insensitive
['HELP'] = 'Help', -- canonical namespaces
['WIKIPEDIA'] = 'WP',
['PROJECT'] = 'Project', -- namespace aliases
['WP'] = 'WP',
['H'] = 'Help',
['MOS'] = 'MOS',
}
--[[--------------------------< E S C A P E _ L U A _ M A G I C _ C H A R S >----------------------------------
Returns a string where all of lua's magic characters have been escaped. This is important because functions like
string.gsub() treat their pattern and replace strings as patterns, not literal strings.
]]
local function escape_lua_magic_chars (argument)
argument = argument:gsub("%%", "%%%%"); -- replace % with %%
argument = argument:gsub("([%^%$%(%)%.%[%]%*%+%-%?])", "%%%1"); -- replace all other lua magic pattern characters
return argument;
end
--[[--------------------------< E R R >------------------------------------------------------------------------
returns formatted error message that is less strident than error() or standard MediaWiki error messages
TODO: add link to template page for help text
]]
local function err (error_msg)
return '<span class="error" style="font-size:100%">' .. error_msg .. ' ([[Template:WP|help]])</span>'; -- tamer, less strident error messages
end
--[[--------------------------< G E T _ C O N T E N T >--------------------------------------------------------
get content from <title> page. On error, use <label> in returned message to identify failing event in the process
returns:
<content>, nil – expected returns
nil, msg – <title> not a valid title
nil, msg – <title> does not exist
nil, msg – <title> is empty
]]
local function get_content (title, label)
local content;
local title_obj = mw.title.new (title); -- get title object for <title>
if not title_obj then -- title object for non-existent valid <title> will have been created; nil else
return nil, label .. ': invalid title: ' .. title; -- return nil when <title> is malformed (not a valid title)
end
content = title_obj:getContent(); -- get content
if not content then
return nil, label .. ': page does not exist: ' .. title; -- return nil when <title> does not exist
elseif '' == content then
return nil, label .. ': page is empty: ' .. title; -- return nil when <title> has no content
end
return content;
end
--[=[-------------------------< W I K I L I N K _ S T R I P >--------------------------------------------------
Wikilink markup does not belong in an anchor id and can / does confuse the code that parses apart citation and
harvc templates so here we remove any wiki markup:
[[link|label]] -> label
[[link]] -> link
]=]
local function wikilink_strip(text)
for wikilink in text:gmatch('%[%b[]%]') do -- get a wikilink
text = text:gsub('%[%b[]%]', '__57r1P__', 1); -- install a marker
if wikilink:match ('^%[%[%s*[Ff]ile:') or wikilink:match ('^%[%[%s*[Ii]mage:') then -- if this wikilink is an image
wikilink = '[IMAGE]'; -- can't display it in a tooltip so use a word; TODO: parse out alt text or caption? worth the effort?
elseif wikilink:match('%[%[.-|(.-)%]%]') then
wikilink = wikilink:match('%[%[.-|(.-)%]%]'); -- extract label from complex [[link|label]] wikilink
else
wikilink = wikilink:match('%[%[(.-)%]%]'); -- extract link from simple [[link]] wikilinks
end
wikilink = escape_lua_magic_chars(wikilink); -- in case there are lua magic characters in wikilink
text = text:gsub('__57r1P__', wikilink, 1); -- replace the marker with the appropriate text
end
return text;
end
--[[--------------------------< T I T L E _ M A K E >----------------------------------------------------------
makes a prefix for the tooltip from {{nutshell}} |title= parameter value, if present, pagename else
Because we are evaluating the content of pagename, we set the frag_flag here when the pagename
has an anchor fragment (<namespace>:<pagename>#<anchor>)
]]
local function title_make (title_param, pagename)
local frag_flag;
local c;
local namespace;
pagename, c = pagename:gsub ('#.*$', ''); -- remove section fragment if any
if 0 < c then
frag_flag = true; -- when fragment removed, set the flag
end
namespace = pagename:match ('^%a+'):upper(); -- extract canonical namespace; convert to upper case for indexing
pagename = pagename:gsub ('^%a+', namespaces[namespace]); -- replace with abbreviation
if '' == title_param then
title_param = '"' .. pagename .. '"'; -- use name of shortcut's target page when |title= missing or empty
end
return title_param, frag_flag;
end
--[[--------------------------< T O O L T I P _ M A K E >------------------------------------------------------
assemble the tooltip (title= attribute value)
]]
local function tooltip_make (title_param, nutshell, frag_flag)
return table.concat ({
title_param, -- the tooltip prefix (usually WP: article name)
('' ~= nutshell and ' in a nutshell: ' or ''), -- when there is nutshell text
nutshell,
(frag_flag and ' (subsection link)' or ''), -- when WP: article name has a fragment
});
end
--[[--------------------------< N U T S H E L L _ T E X T _ G E T >--------------------------------------------
gets text from {{nutshell}} (or redirect) template in shortcut's target page; frame included as argument here
so that this function has access to frame:preprocess()
shortcut is shortcut name with a namespace prefix (WP:BOLD, MOS:MED, H:CS1, etc)
]]
local function nutshell_text_get (shortcut, frame)
local content; -- content of shortcut page then content of target
local target; -- name of shortcut's redirect target
local msg; -- error messages go here
local c; -- general purpose var holds the tally of gsub() replacements made when needed
local title_param; -- {{nutshell}} |title= parameter contents and value used in tooltip rendering
local frag_flag; -- boolean set true when normalized page name has a fragment (WP:<page title>#<anchor name>)
content, msg = get_content (shortcut, 'shortcut'); -- get content of shortcut redirect page
if msg then
return nil, msg;
end
target = mRedirect.getTargetFromText (content); -- get redirect <target title> (page name) from content of redirect page: (#Redirect [[<target title>]]) or nil
if not target then
return nil, 'shortcut: ' .. shortcut .. ' is not a redirect';
end
content, msg = get_content (target, 'target'); -- get content of redirect target
if msg then
return nil, msg;
end
local templatePatterns = {
"{{%s*[Nn]utshell%s*|",
"{{%s*[Pp]olicy in a nutshell%s*|",
"{{%s*[Pp]olicy proposal in a nutshell%s*|",
"{{%s*[Ii]n a nutshell%s*|",
"{{%s*[Ii]nanutshell%s*|",
"{{%s*[Gg]uideline in a nutshell%s*|",
"{{%s*[Gg]uideline one liner%s*|",
"{{%s*[Nn]aming convention in a nutshell%s*|",
"{{%s*[Nn]utshell2%s*|",
"{{%s*[Pp]roposal in a nutshell%s*|",
"{{%s*[Ee]ssay in a nutshell%s*|"
}
local nutshell
for i, pattern in ipairs (templatePatterns) do
local pos = mw.ustring.find (content, pattern)
if pos then
nutshell = mw.ustring.match (content, '%b{}', pos)
break
end
end
if not nutshell then -- nil when there is no recognized nutshell template
title_param, frag_flag = title_make ('', target);
return tooltip_make (title_param, '', frag_flag); -- nutshell doesn't exist so empty string for concatenation
end
-- begin template disassembly - order is important here - rare case where |title= holds a template
nutshell = nutshell:gsub ('^{{[%w%s]*|', ''):gsub ('}}$', ''); -- remove opening {{ and template name then remove closing }}
for t in nutshell:gmatch('%b{}') do -- get an embedded template
nutshell = nutshell:gsub('%b{}', '__57r1P__', 1) -- install a marker
local replacement = frame:preprocess (t); -- get the template's rendering
replacement = escape_lua_magic_chars(replacement); -- in case there are lua magic characters in replacement
nutshell = nutshell:gsub('__57r1P__', replacement, 1) -- replace the marker with the appropriate text
end
nutshell = wikilink_strip (nutshell); -- remove wikilinks
title_param = nutshell:match ('|%s*title%s*=%s*([^|]+)') or ''; -- get title text or an empty string
title_param = mw.text.trim (title_param); -- remove extraneous leading / trailing whitespace
title_param, frag_flag = title_make (title_param, target); -- get content from {{nutshell}} |title= param if present, else concot a title
nutshell = nutshell:gsub ('|%s*title%s*=%s*[^|]*', ''); -- remove title parameter and value; TODO: these two can be made one?
nutshell = nutshell:gsub ('|%s*shortcut%d*%s*[^|]*', ''); -- remove all shortcut parameters and their values
nutshell, c = nutshell:gsub ('%s*|%s*', ' *'); -- replace pipes and get a tally
if 0 < c then
nutshell = '*' .. nutshell; -- if any pipes were replaced, prefix with a splat
end
nutshell = nutshell:gsub ('"', '"'):gsub ('%b<>', ''); -- convert double quote characters to html entities then remove html-like tags
-- end template disassembly
return tooltip_make (title_param, nutshell, frag_flag);
end
--[[--------------------------< M A I N >----------------------------------------------------------------------
template entry point
{{#invoke:Nutshell|main|<shortcut>}} where <shortcut> is shortcut name with or without namespace prefix; BOLD or WP:BOLD
]]
local function main (frame)
local args = getArgs (frame); -- get a table of arguments
local out = {};
local shortcut = args[1]; -- TODO: error check this; no point in continuing without properly formed shortcut
if not shortcut or '' == shortcut then
return err ('no shortcut name given');
end
local namespace, rest = shortcut:match ('^(%a+)(:%w+)');
if namespace then
namespace = namespace:upper();
if not namespaces[namespace] then
return err ('namespace \'' .. namespace .. '\' not recognized in shortcut: ' .. shortcut);
else
shortcut = namespaces[namespace] .. rest;
end
else
shortcut = 'WP:' .. shortcut; -- add WP: namespace
end
local nutshell, error_msg = nutshell_text_get (shortcut, frame); -- pass frame so that nutshell_text_get() has access to frame:preprocess()
if error_msg then
return err (error_msg);
end
table.insert (out, '[['); -- open wikilink
table.insert (out, shortcut); -- add shortcut
if nutshell then
table.insert (out, '|<span title="'); -- pipe, then start the opening span
table.insert (out, nutshell); -- add nutshell text
table.insert (out, '" class="rt-commentedText" style="border-bottom:1px dotted">'); --finish the opening span
table.insert (out, shortcut); -- add shortcut
table.insert (out, '</span>'); -- close the span
end
table.insert (out, ']]'); -- close the wikilink
return table.concat (out); -- concatenate and done
end
--[[--------------------------< E X P O R T E D F U N C T I O N S >------------------------------------------
]]
return {
main = main,
}
Content Disclaimer
Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.
- The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
- There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
- It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
- Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
- Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.