dev
Documentation icon Module documentation
[view] [edit] [history] [purge]

This module takes in text and displays both the input and/or the result. The input supports wikitext formatting and can use links to other pages. The output's wikitext formatting needs to be escaped appropriately (see below).

Usage

{{#invoke:Eval|main|<wikitext to process>}}

For just the code with HTML formatting, utilize {{#invoke:Eval|code|<wikitext to process>}}

For just the unformatted code, utilize {{#invoke:Eval|raw|<wikitext to process>}}

For just the result, utilize {{#invoke:Eval|result|<wikitext to process>}}

Parameters

  • 1: the code to evaluate and display. This parameter is required.
  • nowiki: whether the input is surrounded by nowiki tags. In this case, the module will behave similar to Module:Demo. Default is "no".
  • format: the format of the code section. "inline" will display the code and/or result on the same line, while "block" will display the code in syntaxhighlight. Default is "block".

Escape characters

For technical reasons, attempting to add template code such as {{template}} will copy the contents of the template into the parameters. The same applies for parser tags like <ref>...</ref> and <gallery>...</gallery>. To get around this, using backslash before any of these characters will escape it, similar to escaping in JavaScript or C++.

Escape sequence Output to source code
\e =
\p |
\[ [
\] ]
\{ {
\} }
\< <
\> >
\\ \

This is not relevant when "nowiki" is set to "yes".

Examples

With Formatted Text

{{#invoke:Eval|main|
This is some <b>bold text</b> in the source
}}
Using this code:
This is some bold text in the source
yields:
This is some bold text in the source

{{#invoke:Eval|main|
This is some \&lt;b\&gt;bold text\&lt;/b\&gt; in the source
}}
Using this code:
This is some &lt;b&gt;bold text&lt;/b&gt; in the source
yields:
This is some <b>bold text</b> in the source

{{#invoke:Eval|main|
This is some \<b\>bold text\</b\> in the output
}}
Using this code:
This is some <b>bold text</b> in the output
yields:
This is some bold text in the output

{{#invoke:Eval|main|
I can call a template like \{\{T\pT\}\}
}}
Using this code:
I can call a template like {{T|T}}
yields:
I can call a template like {{T}}
{{#invoke:Eval|main|
I can call a template like \{\{T\pT\}\}
|format=inline}}
Using this code: I can call a template like {{T|T}} yields: I can call a template like {{T}}

{{#invoke:Eval|raw|
I can call a template like \{\{T\pT\}\}
}}
I can call a template like {{T|T}}

{{#invoke:Eval|code|
I can call a template like \{\{T\pT\}\}
}}

I can call a template like {{T|T}}

{{#invoke:Eval|code|
I can call a template like \{\{T\pT\}\}
|format=inline}}
I can call a template like {{T|T}}

{{#invoke:Eval|result|
I can call a template like \{\{T\pT\}\}
}}
I can call a template like {{T}}


{{#invoke:Eval|main|
I can also make a fake template call like \{\{T\{\{!\}\}T\}\}
}}
Using this code:
I can also make a fake template call like {{T{{!}}T}}
yields:
I can also make a fake template call like {{T|T}}

{{#invoke:Eval|main|
To insert a \[\[wikipedia:Backslash\pbackslash\]\] I just use \\
|format=inline}}

Using this code: To insert a [[wikipedia:Backslash|backslash]] I just use \ yields: To insert a backslash I just use \


{{#invoke:Eval|main|
And this is how to insert [[Main Page|links]] into the code
|format=inline}}

Using this code: And this is how to insert links into the code yields: And this is how to insert links into the code


{{#invoke:Eval|main|
And an [https://example.com external link]
|format=inline}}

Using this code: And an external link yields: And an external link


{{#invoke:Eval|main|
If you [[Main Page|try it]] in block mode it may look weird
}}
Using this code:
If you try it in block mode it may look weird
yields:
If you try it in block mode it may look weird

With Nowiki

{{#invoke:Eval|main|
<nowiki>This is some [[Main Page|Link]]</nowiki>
|nowiki=yes}}
Using this code:
This is some [[Main Page|Link]]
yields:
This is some Link

More info

Subpages



local p = {}
local yn = require('Dev:Yesno')
local getArgs = require('Dev: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>&amp;</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._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.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 code = format == 'inline'
		and mw.getCurrentFrame():preprocess("<code>" .. text .. "</code>")
		or mw.getCurrentFrame():preprocess("<code style=\"display:inline-block;\">" .. text .. "</code>")
	return code
end

p.raw = makeInvokeFunc("_raw")
function p._raw(args)
	local nowiki = yn(args['nowiki']) or false
	local text = nowiki 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'])
		and mw.getCurrentFrame():preprocess(mw.text.unstripNoWiki(text))
			or mw.getCurrentFrame():preprocess(
				mw.ustring.gsub(
					mw.ustring.gsub(
						mw.ustring.gsub(
							mw.text.unstripNoWiki(
								p._removeXML(
									p._removeAllLinks(text)
								)
							)
						, '%&lt;', '<')
					, '%&gt;', '>')
				, '%&amp;', '&')
			)
		or ''
	mw.log(result)
	return result
end
return p