Module:Demo/sandbox
Appearance
This is the module sandbox page for Module:Demo (diff). |
This module is rated as ready for general use. It has reached a mature form and is thought to be relatively bug-free and ready for use wherever appropriate. It is ready to mention on help pages and other Wikipedia resources as an option for new users to learn. To reduce server load and bad output, it should be improved by sandbox testing rather than repeated trial-and-error editing. |
Usage
[edit]Usage via templates
[edit]This module supports {{Demo}}
{{#invoke:Demo|main}}
and {{Demo inline}}
{{#invoke:Demo|inline}}
The input must be wrapped in <nowiki>
tags or else it may be processed before the module can read it.
Usage in a module
[edit]If you want to use this in another module (such as to make the output prettier), you can get values like so:
require('Module:demo').get(frame)
Function get()
returns a table containing:
source
= the source code (without<syntaxhighlight>
wrappers, characters substituted with html entities)output
= the execution result of the source.frame
= the frame from which this template took the parameter.
By default, get()
takes the first parameter of frame. If the frame uses a different parameter name for the nowiki-wrapped source, then place that name (as a string) as the second parameter, like so require('Module:demo').get(frame, 'alternate_name')
Example:
local p = {}
function p.main(frame)
local parts = require('Module:demo').get(frame)
return '…Pretty HTML… <pre>' .. parts.source .. '</pre> …More pretty HTML… ' .. parts.output .. ' …Even more pretty HTML…'
end
return p
See also
[edit]- Template:Nowiki template demo which uses Module:Template test case
- Template:Automarkup which uses Module:Automarkup
local p = {}
local yn = require('Module:Yesno')
local getArgs = require('Module:Arguments').getArgs
-- simple module that takes in an input and displays the input and output of a wikitext
-- helper function which gets all the locations of all the matches of a ustring
function p._getAllMatchIndices(text, pattern)
local output = {}
local i = 0
while i ~= nil do
i = mw.ustring.find(text, pattern, i + 1)
if i ~= nil then table.insert(output, i) end
end
return output
end
-- replaces all usages of \[, \], \<, \> \\, \{, and \} with [, ], <, >, \, {, and }
-- also replaces line breaks, carriage returns, and tabs with their appropriate character
function p._escapeAllCharacters(text)
local indices = p._getAllMatchIndices(text, "\\")
local splitText = mw.text.split(text, '')
local skip = false
for k,v in ipairs(indices) do
if not skip then
splitText[v] = ''
local nc = splitText[v + 1]
splitText[v + 1] = (
nc == "e" and '=' or
nc == "p" and '|' or
nc == '[' and mw.getCurrentFrame():preprocess('<nowiki>[</nowiki>') or
nc == ']' and mw.getCurrentFrame():preprocess('<nowiki>]</nowiki>') or
nc == '{' and mw.getCurrentFrame():preprocess('<nowiki>{</nowiki>') or
nc == '}' and mw.getCurrentFrame():preprocess('<nowiki>}</nowiki>') or
nc == '<' and mw.getCurrentFrame():preprocess('<nowiki><</nowiki>') or
nc == '>' and mw.getCurrentFrame():preprocess('<nowiki>></nowiki>') or
nc == '&' and mw.getCurrentFrame():preprocess('<nowiki>&</nowiki>') or
splitText[v + 1]
)
mw.log(splitText[v + 1])
if nc == '\\' then
skip = true
end
else
skip = false
end
end
return table.concat(splitText)
end
function p._escapeHTMLCharCodes(str)
local function replaceHTMLCharCodes(entity)
mw.log(entity)
local charCode = mw.ustring.match(entity, "%d+") and tonumber(mw.ustring.match(entity, "%d+")) or mw.ustring.match(entity, "%w+;")
mw.log(charCode)
if type(charCode) == 'number' then
return mw.ustring.char(charCode)
else
local HTMLCharCodes = {
["amp;"] = "&",
["gt;"] = ">",
["lt;"] = "<"
}
local replacementChar = HTMLCharCodes[charCode] or entity
return replacementChar
end
end
return mw.ustring.gsub(str, "%&%S-;", replaceHTMLCharCodes)
end
function p._removeAllLinks(text)
-- find all [ and ] characters and remove them
local splitText = mw.text.split(text, '')
local numberOfBrackets = 0
local endCharacter = false
for k,v in ipairs(splitText) do
if splitText[k] == '[' then
numberOfBrackets = numberOfBrackets + 1
endCharacter = false
if numberOfBrackets > 2 then numberOfBrackets = 2 else splitText[k] = '' end
elseif splitText[k] == ']' then
numberOfBrackets = numberOfBrackets - 1
endCharacter = false
if numberOfBrackets < 0 then numberOfBrackets = 0 else splitText[k] = '' end
else
if numberOfBrackets == 2 then
if not endCharacter then
endCharacter = splitText[k] == '|'
splitText[k] = ''
end
elseif numberOfBrackets == 1 then
if not endCharacter then
endCharacter = splitText[k] == ' '
splitText[k] = ''
end
end
end
end
return table.concat(splitText)
end
function p._removeXML(text)
-- finds all xml tags and remove them
local splitText = mw.text.split(text, '')
local numberOfBrackets = 0
local numberOfDoubleQuotes = 0
local numberOfSingleQuotes = 0
for k,v in ipairs(splitText) do
if splitText[k] == '<' then
numberOfBrackets = numberOfBrackets + 1
if numberOfBrackets > 1 then numberOfBrackets = 1 else splitText[k] = '' end
elseif splitText[k] == '>' then
numberOfBrackets = numberOfBrackets - 1
if numberOfBrackets < 0 then numberOfBrackets = 0 else splitText[k] = '' end
else
if numberOfBrackets == 1 then
splitText[k] = ''
end
end
end
return table.concat(splitText)
end
-- from Wikipedia
local function makeInvokeFunc(funcName)
return function (frame)
local args = getArgs(frame, {
valueFunc = function (key, value)
if type(value) == 'string' then
value = value:match('^%s*(.-)%s*$') -- Remove whitespace.
if key == 'heading' or value ~= '' then
return value
else
return nil
end
else
return value
end
end
})
return p[funcName](args)
end
end
p.main = makeInvokeFunc("_main")
function p._main(args)
local nowiki = yn(args['nowiki']) or false
local format = args['format'] or 'block'
local code = p._code(args)
local result = p._result(args)
if format == 'inline' then
return 'Using this code: ' .. code .. ' yields: ' .. result
else
return '<dl><dt>Using this code:</dt><dd>'
.. code
.. '</dd><dt>yields: </dt><dd>'
.. result
.. '</dd></dl>'--output the result
end
end
p.inline = makeInvokeFunc("_inline")
function p._inline(args)
args['format'] = 'inline'
return p._main(args)
end
p.block = makeInvokeFunc("_block")
function p._inline(args)
args['format'] = 'block'
return p._main(args)
end
p.code = makeInvokeFunc("_code")
function p._code(args)
local nowiki = yn(args['nowiki']) or false
local text = p._raw(args)
local format = args['format'] or 'block'
local syntaxhighlight = yn(args["syntaxhighlight"]) or true
if not syntaxhighlight then
local code = format == 'inline'
and mw.getCurrentFrame():preprocess("<code>" .. text .. "</code>")
or mw.getCurrentFrame():preprocess("<code style=\"display:inline-block;\">" .. text .. "</code>")
return code
else
local code = format == "inline"
and mw.getCurrentFrame():preprocess("<syntaxhighlight inline lang=\"wikitext\">" .. text .. "</syntaxhighlight>")
or mw.getCurrentFrame():preprocess("<syntaxhighlight lang=\"wikitext\">" .. text .. "</syntaxhighlight>")
return code
end
end
p.raw = makeInvokeFunc("_raw")
function p._raw(args)
local nowiki = yn(args['nowiki']) or false
local syntaxhighlight = yn(args["syntaxhighlight"]) or false
local text = (nowiki or syntaxhighlight) and args[1] or p._escapeAllCharacters(args[1])
mw.log(text)
return text
end
p.result = makeInvokeFunc("_result")
function p._result(args)
local nowiki = yn(args['nowiki']) or false
local text = p._raw(args)
mw.log(p._removeXML(
p._removeAllLinks(text)
))
local result = (yn(args['nowiki']) or yn(args['syntaxhighlight']))
and mw.getCurrentFrame():preprocess(mw.text.unstripNoWiki(text))
or mw.getCurrentFrame():preprocess(
p._escapeHTMLCharCodes(
mw.text.unstripNoWiki(
p._removeXML(
p._removeAllLinks(text)
)
)
)
)
or ''
mw.log(result)
return result
end
return p