Jump to content
Main menu
Main menu
move to sidebar
hide
Navigation
Main page
Recent changes
Random page
Help about MediaWiki
Neighbors
Esassani
Mobai
Glenn
Mors
Creatures
Fish
Insects
Shore-Dwellers
Search
Search
English
Appearance
Create account
Log in
Personal tools
Create account
Log in
Pages for logged out editors
learn more
Contributions
Talk
Editing
Module:Parser
Module
Discussion
English
Read
Edit source
View history
Tools
Tools
move to sidebar
hide
Actions
Read
Edit source
View history
General
What links here
Related changes
Special pages
Page information
Appearance
move to sidebar
hide
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
local p = {} local CHAR_EQUAL = string.byte("=") local CHAR_OPEN_BRACE = string.byte("{") local CHAR_PIPE = string.byte("|") local CHAR_CLOSE_BRACE = string.byte("}") local CHAR_OPEN_BRACKET = string.byte("[") local CHAR_CLOSE_BRACKET = string.byte("]") local CHAR_GREATER_THAN = string.byte(">") local CHAR_LOWER_THAN = string.byte("<") local CHAR_SLASH = string.byte("/") local FormatParser = {} -- methods local FormatParserMetatable = { __index = FormatParser, } function p.getTemplateArgs(page, options) options = options or {} local rawContent = '' if options.custom then rawContent = page else local title = mw.title.makeTitle(options.namespace or '', page) if title == nil then return {} end rawContent = title:getContent() if rawContent == nil or rawContent == '' then return {} end end rawContent = (rawContent:gsub('<!%-%-.-%-%->', '')) .. '\n' -- remove strip markers (e.g., <ref></ref> ) if options.unstrip then rawContent = mw.text.unstrip(rawContent) end local templates = p._parseFormat(rawContent, options.only) -- return only specific template to simplify usage if options.only then templates = templates[options.only] or {} end -- return raw page content too for extra parsing if options.pageContent then templates.PAGECONTENT = rawContent end -- return parsed content return templates end function p._parseFormat(str, only) if not str then return nil end -- TODO consider supporting DPL-style escape characters local parser = { str = str, strLen = #str, i = 1, tokenStart = 1, template = nil } setmetatable(parser, FormatParserMetatable) return parser:parse(only) end function FormatParser:peekByte(offset) return self.str:byte(self.i + (offset or 0)) end function FormatParser:parse(only) local output = {} local currPage while self.i <= self.strLen do if self:peekByte() == CHAR_OPEN_BRACE and self:peekByte(1) == CHAR_OPEN_BRACE then currPage = self:parseTransclude() elseif self.template ~= nil then if (only ~= nil and self.template == only) or only == nil then if output[self.template] == nil then output[self.template] = currPage elseif output[self.template][1] ~= nil and type(output[self.template][1]) == 'table' then table.insert(output[self.template], currPage) else local temp = output[self.template] output[self.template] = {} table.insert(output[self.template], temp) table.insert(output[self.template], currPage) end end currPage = nil self.template = nil end self.i = self.i + 1 end return output end -- note: assumes all parser functions accept named args in all positions -- (but in the actual wikitext parser, some (e.g., "#if") don't accept any, -- and some don't accept them in certain positions (e.g., first arg of "#invoke")) function FormatParser:parseTransclude() local start = self.i self.i = self.i + 2 -- advance past {{ self.tokenStart = self.i local currPart = {value = {}} local output = {} -- note: always adds to currPart.value. when = is reached, moves currPart.value to currPart.name. while self.i <= self.strLen do if not self:tryParsingOpen(currPart.value) then local currChar = self:peekByte() if currChar == CHAR_PIPE then if self.template == nil then local name = self:parseString() if name ~= nil and name ~= '' then self.template = (mw.text.trim(name):gsub('_', ' ')) end end self:parseStringInto(currPart.value) self.tokenStart = self.i+1 --include param to data if valid if currPart.name and #currPart.name>0 and currPart.value then currPart.name = mw.text.trim(table.concat(currPart.name)) currPart.value = mw.text.unstrip(mw.text.trim(table.concat(currPart.value))) output[currPart.name] = currPart.value elseif currPart.value then currPart.value = mw.text.unstrip(mw.text.trim(table.concat(currPart.value))) if currPart.value ~= self.template then table.insert(output, currPart.value) end end currPart = {value = {}} elseif currChar == CHAR_EQUAL then if not currPart.name then self:parseStringInto(currPart.value) self.tokenStart = self.i+1 currPart.name = currPart.value currPart.value = {} end elseif currChar == CHAR_CLOSE_BRACE then if self:peekByte(1) == CHAR_CLOSE_BRACE then if self.template == nil then local name = self:parseString() if name ~= nil and name ~= '' then self.template = mw.text.trim(name) end end self:parseStringInto(currPart.value) self.i = self.i+1 --include param to data if valid if currPart.name and #currPart.name>0 and currPart.value and #currPart.value>0 then currPart.name = mw.text.trim(table.concat(currPart.name)) currPart.value = mw.text.unstrip(mw.text.trim(table.concat(currPart.value))) output[currPart.name] = currPart.value elseif currPart.value and #currPart.value>0 then currPart.value = mw.text.unstrip(mw.text.trim(table.concat(currPart.value))) if currPart.value ~= self.template then table.insert(output, currPart.value) end end return output end end end self.i = self.i + 1 end local issue = self:parseString() mw.logObject(issue, 'issue in: ') mw.logObject(self.str, 'page: ') mw.logObject(output, 'up to now: ') error("Unmatched {{ at position " .. start) end --- Add a string that ends on the character before the current one. function FormatParser:parseString(offset) if self.tokenStart ~= self.i then return self.str:sub(self.tokenStart, self.i + (offset or -1)) end end function FormatParser:parseStringInto(node, offset) local v = self:parseString(offset) if v then table.insert(node, v) end end -- close tokens and | = are handled in transclude/replace modes function FormatParser:tryParsingOpen(node) local parseMode local currChar = self:peekByte() local nextChar = self:peekByte(1) if currChar == CHAR_OPEN_BRACE then if nextChar == CHAR_PIPE then parseMode = self.parseTable elseif nextChar == CHAR_OPEN_BRACE and self.template ~= nil and self.template ~= '' then parseMode = self.parseTranscludeBasic end elseif currChar == CHAR_OPEN_BRACKET then if nextChar == CHAR_OPEN_BRACKET then parseMode = self.parseLink end elseif currChar == CHAR_LOWER_THAN then local tag = self:parseString(10) or '' if tag:find('^.?<?gallery') or tag:find('^.?<?nowiki') then parseMode = self.parseTag end end if parseMode then self:parseStringInto(node) parseMode(self, node) self.tokenStart = self.i + 1 end return parseMode ~= nil end function FormatParser:parseTranscludeBasic(output) local start = self.i self.tokenStart = self.i self.i = self.i + 2 while self.i <= self.strLen do if not self:tryParsingOpen(output) then if self:peekByte() == CHAR_CLOSE_BRACE and self:peekByte(1) == CHAR_CLOSE_BRACE then self.i = self.i + 1 self:parseStringInto(output, 0) return output end end self.i = self.i + 1 end local issue = self:parseString() mw.logObject(issue, 'issue in: ') mw.logObject(self.str, 'entire page: ') error("Unmatched {{ at position " .. start) end function FormatParser:parseTag(output) local start = self.i self.tokenStart = self.i local count = 0 function findLowerThan() while self.i <= self.strLen do local currChar = self:peekByte() if currChar == CHAR_GREATER_THAN then return end self.i = self.i + 1 end end while self.i <= self.strLen do local currChar = self:peekByte() local nextChar = self:peekByte(1) if currChar == CHAR_LOWER_THAN and nextChar ~= CHAR_SLASH then count = count + 1 findLowerThan() elseif currChar == CHAR_LOWER_THAN and nextChar == CHAR_SLASH then count = count - 1 findLowerThan() end if count == 0 then self.i = self.i + 1 self:parseStringInto(output, 0) return output end self.i = self.i + 1 end local issue = self:parseString() mw.logObject(issue, 'issue in: ') mw.logObject(self.str, 'entire page: ') error("Unmatched tag at position " .. start) end function FormatParser:parseLink(output) local start = self.i self.tokenStart = self.i self.i = self.i + 2 while self.i <= self.strLen do if not self:tryParsingOpen(output) then if self:peekByte() == CHAR_CLOSE_BRACKET and self:peekByte(1) == CHAR_CLOSE_BRACKET then self.i = self.i + 1 self:parseStringInto(output, 0) return output end end self.i = self.i + 1 end local issue = self:parseString() mw.logObject(issue, 'issue in: ') mw.logObject(self.str, 'entire page: ') error("Unmatched [[ at position " .. start) end function FormatParser:parseTable(output) local start = self.i self.tokenStart = self.i self.i = self.i + 2 while self.i <= self.strLen do if not self:tryParsingOpen(output) then if self:peekByte() == CHAR_PIPE and self:peekByte(1) == CHAR_CLOSE_BRACE then self.i = self.i + 1 self:parseStringInto(output, 0) return output end end self.i = self.i + 1 end local issue = self:parseString() mw.logObject(issue, 'issue in: ') mw.logObject(self.str, 'entire page: ') error("Unmatched {| at position " .. start) end function p.removeBlank(tab) if type(tab) ~= 'table' then return false end for _ in pairs(tab) do return true end return false end -- entry point for other modules p.FormatParserMetatable = FormatParserMetatable return p
Summary:
Please note that all contributions to The Petit Planet Wiki are considered to be released under the Creative Commons Attribution-NonCommercial-ShareAlike (see
Petit Planet:Copyrights
for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource.
Do not submit copyrighted work without permission!
Cancel
Editing help
(opens in new window)
Preview page with this template
Below are commonly used wikitext from
MediaWiki:Edittools
. Click on any to insert them in the edit box.
File Pages
==Summary==
==Licensing==
{{Fairuse}}
{{File|}}
Dynamic Page List
¦
²
«
»
²{¦}²
«»
«/»
«!----»
Array in DPL
¹
^2{
}^2
^2{¹}^2
Parser Functions
{{#if:||}}
{{#if:<condition>|<result if true>|<result if false>}}
{{#ifeq:|||}}
{{#ifeq:<text1>|<text2>|<result if text1=text2>|<result if text1≠text2>}}
{{#expr:}}
{{#expr:<mathematical expression>}}
{{#switch:||#default=}}
{{#switch:<text1>|<text2>=<result if text1=text2>|<text3>=<result if text1=text3>|#default=<result if no valid match>}}
{{#replace:||}}
{{#replace:<text1>|<plain text to find in text1>|<plain text to insert in place of the text found>}}
{{#titleparts:}}
{{#replace:<page name>}}
{{#tag:|}}
{{#tag:<name of html tag>|<content inside html tag>}}
Markup
{{}}
|
[]
[[]]
[[Category:]]
#REDIRECT [[]] [[Category:Redirect Pages]]
<code></code>
<includeonly></includeonly>
<noinclude></noinclude>
<nowiki></nowiki>
<!---->
<br>
§
Notices
{{Stub|}}
{{Stub Dialogue}}
{{Upcoming}}
{{Under Construction}}
{{Placeholder|}}
Magic Words
{{!}}
{{formatnum:}}
{{lc:}}
{{uc:}}
{{PAGENAME}}
{{FULLPAGENAME}}
{{ROOTPAGENAME}}
{{BASEPAGENAME}}
{{SUBPAGENAME}}
{{DISPLAYTITLE:|noreplace}}
__TOC__
__NOTOC__
__EXPECTUNUSEDCATEGORY__
__HIDDENCAT__
HTML Entities
—
,
­
Template used on this page:
Module:Parser/doc
(
edit
)