local concat = table.concat
local find = string.find
local sub = string.sub
local function remove_comments(str, pre)
local pos1 = find(str, "<!--", nil, true)
if not pos1 then
return str
end
local pos2 = find(str, "-->", pos1 + 4, true)
if not pos2 then
return pre and sub(str, 1, pos1 - 1) or str
end
local ret = sub(str, 1, pos1 - 1)
pos1 = pos2 + 3
pos2 = find(str, "<!--", pos1, true)
if not pos2 then
return ret .. sub(str, pos1)
end
local pos3 = find(str, "-->", pos2 + 4, true)
if not pos3 then
return ret .. sub(str, pos1, pre and pos2 - 1 or nil)
end
ret = {ret, sub(str, pos1, pos2 - 1)}
local n = 2
while true do
pos1 = pos3 + 3
pos2 = find(str, "<!--", pos1, true)
if not pos2 then
return concat(ret) .. sub(str, pos1)
end
pos3 = find(str, "-->", pos2 + 4, true)
if not pos3 then
return concat(ret) .. sub(str, pos1, pre and pos2 - 1 or nil)
end
n = n + 1
ret = sub(str, pos1, pos2 - 1)
end
end
--[==[Removes any HTML comments from the input text. `stage` can be one of three options:
* {"PRE"} (default) applies the method used by MediaWiki's preprocessor: all {{code|html|<nowiki><!-- ... --></nowiki>}} pairs are removed, as well as any text after an unclosed {{code|html|<nowiki><!--</nowiki>}}. This is generally suitable when parsing raw template or ] code. (Note, however, that the actual method used by the preprocessor is considerably more complex and differs under certain conditions (e.g. comments inside nowiki tags); if full accuracy is absolutely necessary, use ] instead).
* {"POST"} applies the method used to generate the final page output once all templates have been expanded: it loops over the text, removing any {{code|html|<nowiki><!-- ... --></nowiki>}} pairs until no more are found (e.g. {{code|html|<nowiki><!-<!-- ... -->- ... --></nowiki>}} would be fully removed), but any unclosed {{code|html|<nowiki><!--</nowiki>}} is ignored. This is suitable for handling links embedded in template inputs, where the {"PRE"} method will have already been applied by the native parser.
* {"BOTH"} applies {"PRE"} then {"POST"}.]==]
return function(str, stage)
if stage == nil or stage == "PRE" then
return remove_comments(str, true)
elseif stage == "BOTH" then
str = remove_comments(str, true)
elseif stage ~= "POST" then
error("bad argument #2 to 'remove_comments' (expected PRE, POST, or BOTH)", 2)
end
while true do
local processed = remove_comments(str)
if processed == str then
return str
end
str = processed
end
end