Toggle menu
15
236
75
27.7K
Kenshi Wiki
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.
Refer to Module:Demo



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>&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._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