Difference between pages "Gandora the Dragon of Destruction" and "Module:Input parser"
(Difference between pages)
(Also check if the linked text contains only whitespace) |
|||
Line 1: | Line 1: | ||
− | + | --[[ | |
− | + | Common functions for helping with extracting data from wikitext input | |
− | + | ]]-- | |
− | + | ||
− | + | ||
− | + | local inputParser = {} | |
− | + | ||
− | + | -- Convert an unordered list (bulleted list) to an array (i.e. table) | |
− | + | -- e.g. `'\n* A\n* B\n* C'` -> `{ 'A', 'B', 'C' }` | |
− | + | -- | |
− | + | -- @param text string unordered list in wikitext | |
− | + | -- @return table | |
− | + | function inputParser.ulToArray(text) | |
− | + | -- No text, return empty table | |
− | + | if (not text) then return {} end | |
− | + | ||
− | + | -- remove initial `*` and spacing | |
− | + | local trimmedText = mw.text.trim(text, '* \n') | |
− | + | ||
− | + | -- If the text is empty or only contained whitespace, return empty table | |
− | + | if (trimmedText == '') then return {} end | |
− | + | ||
− | + | -- Split by `*`, surrounded in optional spaces | |
− | + | return mw.text.split(trimmedText, '%s*\*%s*') | |
− | + | end | |
− | + | ||
− | + | -- Parse data from a wikitext link | |
− | + | -- e.g. `'[[Metal Fiend Token (manga)|Metal Devil]]'` -> `{ link = 'Metal Fiend Token (manga)', text = 'Metal Devil' }` | |
− | + | -- @param linkInput string | |
− | + | -- @return table | |
− | + | function inputParser.parseLink(linkInput) | |
− | + | if (not linkInput) then | |
− | + | return { link = nil, text = nil } | |
− | + | end | |
− | | | + | |
− | + | --[[ | |
− | + | Pattern for a link in wikitext | |
− | + | - two opening square brackets | |
− | + | - any number of non-`|` non-`]` characters <-- first capture group | |
− | + | - optional pipe character | |
− | + | - optional amount of any characters <-- second capture group | |
− | + | - two closing square brackets | |
− | + | ]]-- | |
− | + | local pattern = '%[%[([^|%]]*)|?(.-)%]%]' | |
− | + | ||
− | + | -- Store the first capture group as the link | |
− | + | -- And the second as the display text | |
− | + | local link, text = linkInput:match(pattern) | |
− | + | ||
− | + | -- If the text doesn't match the pattern, assume there's no link, only text | |
− | + | if (not link) then | |
− | + | return { link = nil, text = linkInput } | |
− | + | end | |
− | + | ||
− | + | -- If the text is empty or only contains whitespace, default it to the link | |
− | + | if (not text or (type(text) == 'string' and mw.text.trim(text) == '')) then | |
− | + | text = link | |
− | + | end | |
− | + | ||
− | + | return { link = link, text = text } | |
− | + | end | |
− | + | ||
− | + | --[[ | |
− | + | A number of modules accept input formatted like this: | |
− | + | List item 1; // arg1::value1; arg2; arg3::value3 | |
− | + | List Item 2; // arg1::value1; arg2; arg3::value3 | |
− | + | ||
− | + | This function gets the arguments after the double forward slash. | |
− | + | ||
− | + | e.g. | |
− | + | Mystical Moon; 800 // debut; mentioned; dub; qty::2 | |
− | + | becomes | |
− | + | { ['debut'] = true, ['mentioned'] = true, ['dub'] = true, ['qty'] = '2' } | |
− | + | ]]-- | |
− | + | -- | |
− | ''' | + | -- @param lineText string |
− | + | -- @return table | |
− | + | function inputParser.getLineArgs(lineText) | |
− | * | + | -- Get text after the `//` |
− | + | local argsText = mw.text.split(lineText, '%s*//%s*')[2] or '' | |
− | + | ||
− | + | -- Split by semicolons surrounded by any amount of spaces | |
− | + | -- e.g. `'[[Mystical Moon]] // debut; mentioned; dub; qty::2'` | |
− | + | -- becomes `{ 'debut', 'mentioned', 'dub', 'qty::2' }` | |
− | + | local argsArr = mw.text.split(argsText, '%s*;%s*') | |
− | + | ||
− | + | -- Pattern for matching two pieces of text separated by a double semicolon | |
− | + | local pattern = '(.*)::(.*)' | |
− | + | ||
− | + | local args = {} | |
− | + | ||
− | + | -- Parse the named variables in the list | |
− | + | -- e.g. `{ 'debut', 'mentioned', 'dub', 'qty::2' }` | |
− | + | -- becomes `{ ['debut'] = true, ['mentioned'] = true, ['dub'] = true, ['qty'] = '2' } | |
− | + | for _, arg in pairs(argsArr) do | |
− | + | local param, value = arg:match(pattern) | |
− | + | ||
− | + | if (not param) then | |
− | + | -- table.insert(args, arg) | |
+ | args[arg] = true | ||
+ | else | ||
+ | args[param] = value | ||
+ | end | ||
+ | end | ||
+ | |||
+ | return args | ||
+ | end | ||
+ | |||
+ | return inputParser |
Latest revision as of 20:47, 1 April 2024
--[[
Common functions for helping with extracting data from wikitext input
]]--
local inputParser = {}
-- Convert an unordered list (bulleted list) to an array (i.e. table)
-- e.g. `'\n* A\n* B\n* C'` -> `{ 'A', 'B', 'C' }`
--
-- @param text string unordered list in wikitext
-- @return table
function inputParser.ulToArray(text)
-- No text, return empty table
if (not text) then return {} end
-- remove initial `*` and spacing
local trimmedText = mw.text.trim(text, '* \n')
-- If the text is empty or only contained whitespace, return empty table
if (trimmedText == '') then return {} end
-- Split by `*`, surrounded in optional spaces
return mw.text.split(trimmedText, '%s*\*%s*')
end
-- Parse data from a wikitext link
-- e.g. `'[[Metal Fiend Token (manga)|Metal Devil]]'` -> `{ link = 'Metal Fiend Token (manga)', text = 'Metal Devil' }`
-- @param linkInput string
-- @return table
function inputParser.parseLink(linkInput)
if (not linkInput) then
return { link = nil, text = nil }
end
--[[
Pattern for a link in wikitext
- two opening square brackets
- any number of non-`|` non-`]` characters <-- first capture group
- optional pipe character
- optional amount of any characters <-- second capture group
- two closing square brackets
]]--
local pattern = '%[%[([^|%]]*)|?(.-)%]%]'
-- Store the first capture group as the link
-- And the second as the display text
local link, text = linkInput:match(pattern)
-- If the text doesn't match the pattern, assume there's no link, only text
if (not link) then
return { link = nil, text = linkInput }
end
-- If the text is empty or only contains whitespace, default it to the link
if (not text or (type(text) == 'string' and mw.text.trim(text) == '')) then
text = link
end
return { link = link, text = text }
end
--[[
A number of modules accept input formatted like this:
List item 1; // arg1::value1; arg2; arg3::value3
List Item 2; // arg1::value1; arg2; arg3::value3
This function gets the arguments after the double forward slash.
e.g.
Mystical Moon; 800 // debut; mentioned; dub; qty::2
becomes
{ ['debut'] = true, ['mentioned'] = true, ['dub'] = true, ['qty'] = '2' }
]]--
--
-- @param lineText string
-- @return table
function inputParser.getLineArgs(lineText)
-- Get text after the `//`
local argsText = mw.text.split(lineText, '%s*//%s*')[2] or ''
-- Split by semicolons surrounded by any amount of spaces
-- e.g. `'[[Mystical Moon]] // debut; mentioned; dub; qty::2'`
-- becomes `{ 'debut', 'mentioned', 'dub', 'qty::2' }`
local argsArr = mw.text.split(argsText, '%s*;%s*')
-- Pattern for matching two pieces of text separated by a double semicolon
local pattern = '(.*)::(.*)'
local args = {}
-- Parse the named variables in the list
-- e.g. `{ 'debut', 'mentioned', 'dub', 'qty::2' }`
-- becomes `{ ['debut'] = true, ['mentioned'] = true, ['dub'] = true, ['qty'] = '2' }
for _, arg in pairs(argsArr) do
local param, value = arg:match(pattern)
if (not param) then
-- table.insert(args, arg)
args[arg] = true
else
args[param] = value
end
end
return args
end
return inputParser