Mô đun:Wikitext Parsing

require("strict")
--Helper functions
local function startswith(text, subtext)
	return string.sub(text, 1, #subtext) == subtext
end
local function endswith(text, subtext)
	return string.sub(text, -#subtext, -1) == subtext
end
local function allcases(s)
	return s:gsub("%a", function(c) 
		return ""..c:upper()..c:lower()..""
	end)
end
local trimcache = {}
local whitespace = {" "=1, "\n"=1, "\t"=1, "\r"=1}
local function cheaptrim(str) --mw.text.trim is surprisingly expensive, so here's an alternative approach
	local quick = trimcachestr
	if quick then
		return quick
	else
		-- local out = string.gsub(str, "^%s*(.-)%s*$", "%1")
		local lowEnd
		for i = 1,#str do
			if not whitespacestring.sub(str, i, i) then
				lowEnd = i
				break
			end
		end
		if not lowEnd then
			trimcachestr = ""
			return ""
		end
		for i = #str,1,-1 do
			if not whitespacestring.sub(str, i, i) then
				local out = string.sub(str, lowEnd, i)
				trimcachestr = out
				return out
			end
		end
	end
end
--= Implementation notes
---- NORMAL HTML TAGS ----
Tags are very strict on how they want to start, but loose on how they end.
The start must strictly follow ) with no room for whitespace in
the tag's name, but may then flow as they want afterwards, making
valid
There's no sense of escaping 
E.g.
"> will end at \> despite it being inside a quote
error"> will not process the larger div
If a tag has no end, it will consume all text instead of not processing
---- NOPROCESSING TAGS (nowiki, pre, syntaxhighlight, source, etc.) ----
(In most comments,  will not be mentioned. This is because it is the
deprecated version of )
No-Processing tags have some interesting differences to the above rules.
For example, their syntax is a lot stricter. While an opening tag appears to
follow the same set of rules, A closing tag can't have any sort of extra
formatting period. While  is valid,  isn't - only
newlines and spaces/tabs are allowed in closing tags.
Note that, even though  tags cause a visual change when the ending tag has
extra formatting, it won't cause the no-processing effects. For some reason, the
format must be strict for that to apply.
Both the content inside the tag pair and the content inside each side of the
pair is not processed. E.g.  would have both of the 
escaped in practice.
When something in the code is referenced to as a "Nowiki Tag", it means a tag
which causes wiki text to not be processed, which includes ") then --self-closing tag (we are our own ending)
			return {
				Tag = tagName,
				Start = startingTag,
				Content = "", End = "",
				Length = #startingTag
			}
		else
			local endingTagStart, endingTagEnd = string.find(text, "", scanPosition)
			if endingTagStart then --Regular tag formation
				local endingTag = string.sub(text, endingTagStart, endingTagEnd)
				local tagContent = string.sub(text, nextCloser+1, endingTagStart-1)
				return {
					Tag = tagName,
					Start = startingTag,
					Content = tagContent,
					End = endingTag,
					Length = #startingTag + #tagContent + #endingTag
				}
			else --Content inside still needs escaping (also linter error!)
				return {
					Tag = tagName,
					Start = startingTag,
					Content = "", End = "",
					Length = #startingTag
				}
			end
		end
	end
	return nil
end
local function TestForComment(text, scanPosition) --Like TestForNowikiTag but for 
	if string.match(text, "^", scanPosition+4, true)
		if commentEnd then
			return {
				Start = "",
				Content = string.sub(text, scanPosition+4, commentEnd-1),
				Length = commentEnd-scanPosition+3
			}
		else --Consumes all text if not given an ending
			return {
				Start = ""
				local newTagEnd = 
					Tag.End == "" and "" or --Respect no tag ending
					""
				local newContent = mw.text.nowiki(Tag.Content)
				newtext#newtext+1 = newTagStart .. newContent .. newTagEnd
				scanPosition = scanPosition + Tag.Length
			else --Nothing special, move on...
				newtext#newtext+1 = string.sub(text, scanPosition, scanPosition)
				scanPosition = scanPosition + 1
			end
		end
	end
	return table.concat(newtext, "")
end
--= Implementation notes
This function is an alternative to Transcluder's getParameters which considers
the potential for a singular { or } or other odd syntax that %b doesn't like to
be in a parameter's value.
When handling the difference between