Latest revision |
Your text |
Line 1: |
Line 1: |
| --[[ | | -- This module provides several methods to generate test cases. |
| A module for generating test case templates.
| |
| | |
| This module incorporates code from the English Wikipedia's "Testcase table"
| |
| module,[1] written by Frietjes [2] with contributions by Mr. Stradivarius [3]
| |
| and Jackmcbarn,[4] and the English Wikipedia's "Testcase rows" module,[5]
| |
| written by Mr. Stradivarius.
| |
| | |
| The "Testcase table" and "Testcase rows" modules are released under the
| |
| CC BY-SA 3.0 License [6] and the GFDL.[7]
| |
| | |
| License: CC BY-SA 3.0 and the GFDL
| |
| Author: Mr. Stradivarius
| |
| | |
| [1] https://en.wikipedia.org/wiki/Module:Testcase_table
| |
| [2] https://en.wikipedia.org/wiki/User:Frietjes
| |
| [3] https://en.wikipedia.org/wiki/User:Mr._Stradivarius
| |
| [4] https://en.wikipedia.org/wiki/User:Jackmcbarn
| |
| [5] https://en.wikipedia.org/wiki/Module:Testcase_rows
| |
| [6] https://en.wikipedia.org/wiki/Wikipedia:Text_of_Creative_Commons_Attribution-ShareAlike_3.0_Unported_License
| |
| [7] https://en.wikipedia.org/wiki/Wikipedia:Text_of_the_GNU_Free_Documentation_License
| |
| ]]
| |
|
| |
|
| -- Load required modules | | -- Load required modules |
Line 54: |
Line 33: |
| getFullPage = true, | | getFullPage = true, |
| getName = true, | | getName = true, |
| makeHeader = true, | | makeHeading = true, |
| getOutput = true | | getOutput = true |
| } | | } |
Line 94: |
Line 73: |
|
| |
|
| function Template:getFullPage() | | function Template:getFullPage() |
| if not self.template then | | if self.template then |
| return self.title.prefixedText
| |
| elseif self.template:sub(1, 7) == '#invoke' then
| |
| return 'Module' .. self.template:sub(8):gsub('|.*', '')
| |
| else
| |
| local strippedTemplate, hasColon = self.template:gsub('^:', '', 1) | | local strippedTemplate, hasColon = self.template:gsub('^:', '', 1) |
| hasColon = hasColon > 0 | | hasColon = hasColon > 0 |
Line 110: |
Line 85: |
| return mw.site.namespaces[10].name .. ':' .. strippedTemplate | | return mw.site.namespaces[10].name .. ':' .. strippedTemplate |
| end | | end |
| | else |
| | return self.title.prefixedText |
| end | | end |
| end | | end |
Line 135: |
Line 112: |
| end | | end |
|
| |
|
| function Template:makeHeader() | | function Template:makeHeading() |
| return self.heading or self:makeBraceLink() | | return self.heading or self:makeBraceLink() |
| end | | end |
|
| |
|
| function Template:getInvocation(format) | | function Template:getInvocation(format) |
| local invocation = self._invocation:getInvocation{ | | local invocation = self._invocation:getInvocation(self:getName()) |
| template = self:getName(),
| |
| requireMagicWord = self.requireMagicWord,
| |
| }
| |
| if format == 'code' then | | if format == 'code' then |
| invocation = '<code>' .. mw.text.nowiki(invocation) .. '</code>' | | invocation = '<code>' .. mw.text.nowiki(invocation) .. '</code>' |
| elseif format == 'kbd' then
| |
| invocation = '<kbd>' .. mw.text.nowiki(invocation) .. '</kbd>'
| |
| elseif format == 'plain' then | | elseif format == 'plain' then |
| invocation = mw.text.nowiki(invocation) | | invocation = mw.text.nowiki(invocation) |
Line 160: |
Line 132: |
|
| |
|
| function Template:getOutput() | | function Template:getOutput() |
| local protect = require('Module:Protect') | | return self._invocation:getOutput(self:getName()) |
| -- calling self._invocation:getOutput{...}
| |
| return protect(self._invocation.getOutput)(self._invocation, {
| |
| template = self:getName(),
| |
| requireMagicWord = self.requireMagicWord,
| |
| })
| |
| end | | end |
|
| |
|
Line 181: |
Line 148: |
| columns = 'renderColumns', | | columns = 'renderColumns', |
| rows = 'renderRows', | | rows = 'renderRows', |
| tablerows = 'renderRows',
| |
| inline = 'renderInline',
| |
| cells = 'renderCells',
| |
| default = 'renderDefault' | | default = 'renderDefault' |
| } | | } |
Line 194: |
Line 158: |
| -- numbered, whereas general options are not. | | -- numbered, whereas general options are not. |
| local generalOptions, templateOptions = {}, {} | | local generalOptions, templateOptions = {}, {} |
| for k, v in pairs(options) do | | do |
| local prefix, num
| | local optionNum = {} -- a unique key for option numbers inside templateOptions |
| if type(k) == 'string' then
| | local rawTemplateOptions = {} |
| prefix, num = k:match('^(.-)([1-9][0-9]*)$')
| | for k, v in pairs(options) do |
| | local prefix, num |
| | if type(k) == 'string' then |
| | prefix, num = k:match('^(.-)([1-9][0-9]*)$') |
| | end |
| | if prefix then |
| | num = tonumber(num) |
| | rawTemplateOptions[num] = rawTemplateOptions[num] or {} |
| | rawTemplateOptions[num][prefix] = v |
| | rawTemplateOptions[num][optionNum] = num -- record for use in error messages |
| | else |
| | generalOptions[k] = v |
| | end |
| end | | end |
| if prefix then
| |
| num = tonumber(num)
| |
| templateOptions[num] = templateOptions[num] or {}
| |
| templateOptions[num][prefix] = v
| |
| else
| |
| generalOptions[k] = v
| |
| end
| |
| end
| |
|
| |
| -- Set general options
| |
| generalOptions.showcode = yesno(generalOptions.showcode)
| |
| generalOptions.showheader = yesno(generalOptions.showheader) ~= false
| |
| generalOptions.showcaption = yesno(generalOptions.showcaption) ~= false
| |
| generalOptions.collapsible = yesno(generalOptions.collapsible)
| |
| generalOptions.notcollapsed = yesno(generalOptions.notcollapsed)
| |
| generalOptions.wantdiff = yesno(generalOptions.wantdiff)
| |
| obj.options = generalOptions
| |
|
| |
|
| -- Preprocess template args
| | -- Add default template options |
| for num, t in pairs(templateOptions) do
| | rawTemplateOptions[1] = rawTemplateOptions[1] or {} |
| if t.showtemplate ~= nil then | | rawTemplateOptions[2] = rawTemplateOptions[2] or {} |
| t.showtemplate = yesno(t.showtemplate) | | if rawTemplateOptions[1].template and not rawTemplateOptions[2].template then |
| | rawTemplateOptions[2].template = rawTemplateOptions[1].template .. |
| | '/' .. obj.cfg.sandboxSubpage |
| end | | end |
| end
| | if not rawTemplateOptions[1].template then |
| | | rawTemplateOptions[1].title = mw.title.getCurrentTitle().basePageTitle |
| -- Set up first two template options tables, so that if only the
| |
| -- "template3" is specified it isn't made the first template when the
| |
| -- the table options array is compressed.
| |
| templateOptions[1] = templateOptions[1] or {}
| |
| templateOptions[2] = templateOptions[2] or {}
| |
| | |
| -- Allow the "template" option to override the "template1" option for
| |
| -- backwards compatibility with [[Module:Testcase table]].
| |
| if generalOptions.template then
| |
| templateOptions[1].template = generalOptions.template | |
| end
| |
| | |
| -- Add default template options
| |
| if templateOptions[1].template and not templateOptions[2].template then
| |
| templateOptions[2].template = templateOptions[1].template ..
| |
| '/' .. obj.cfg.sandboxSubpage | |
| end
| |
| if not templateOptions[1].template then
| |
| templateOptions[1].title = mw.title.getCurrentTitle().basePageTitle
| |
| end
| |
| if not templateOptions[2].template then
| |
| templateOptions[2].title = templateOptions[1].title:subPageTitle(
| |
| obj.cfg.sandboxSubpage
| |
| )
| |
| end
| |
| | |
| -- Remove template options for any templates where the showtemplate
| |
| -- argument is false. This prevents any output for that template.
| |
| for num, t in pairs(templateOptions) do
| |
| if t.showtemplate == false then
| |
| templateOptions[num] = nil
| |
| end | | end |
| end
| | if not rawTemplateOptions[2].template then |
| | | rawTemplateOptions[2].title = rawTemplateOptions[1].title:subPageTitle( |
| -- Check for missing template names.
| | obj.cfg.sandboxSubpage |
| for num, t in pairs(templateOptions) do
| | ) |
| if not t.template and not t.title then | |
| error(obj:message( | |
| 'missing-template-option-error', | |
| num, num
| |
| ), 2) | |
| end | | end |
| end
| |
|
| |
|
| -- Compress templateOptions table so we can iterate over it with ipairs.
| | -- Remove gaps in the numbered options |
| templateOptions = (function (t)
| |
| local nums = {} | | local nums = {} |
| for num in pairs(t) do | | for num in pairs(rawTemplateOptions) do |
| nums[#nums + 1] = num | | nums[#nums + 1] = num |
| end | | end |
| table.sort(nums) | | table.sort(nums) |
| local ret = {}
| |
| for i, num in ipairs(nums) do | | for i, num in ipairs(nums) do |
| ret[i] = t[num] | | templateOptions[i] = rawTemplateOptions[num] |
| end | | end |
| return ret
| |
| end)(templateOptions)
| |
|
| |
|
| -- Don't require the __TEMPLATENAME__ magic word for nowiki invocations if
| | -- Check that there are no missing template options. |
| -- there is only one template being output.
| | for i = 3, #templateOptions do -- Defaults have already been added for 1 and 2. |
| if #templateOptions <= 1 then
| | local t = templateOptions[i] |
| templateOptions[1].requireMagicWord = false
| | if not t.template then |
| | local num = t[optionNum] |
| | error(obj:message( |
| | 'missing-template-option-error', |
| | num, num |
| | ), 2) |
| | end |
| | end |
| end | | end |
|
| |
|
| mw.logObject(templateOptions) | | -- Set general options |
| | generalOptions.showcode = yesno(generalOptions.showcode) |
| | generalOptions.collapsible = yesno(generalOptions.collapsible) |
| | obj.options = generalOptions |
|
| |
|
| -- Make the template objects | | -- Make the template objects |
| obj.templates = {} | | obj.templates = {} |
| for i, options in ipairs(templateOptions) do | | for i, t in ipairs(templateOptions) do |
| table.insert(obj.templates, Template.new(invocationObj, options)) | | table.insert(obj.templates, Template.new(invocationObj, t)) |
| end
| |
| | |
| -- Add tracking categories. At the moment we are only tracking templates
| |
| -- that use any "heading" parameters or an "output" parameter.
| |
| obj.categories = {}
| |
| for k, v in pairs(options) do
| |
| if type(k) == 'string' and k:find('heading') then
| |
| obj.categories['Test cases using heading parameters'] = true
| |
| elseif k == 'output' then
| |
| obj.categories['Test cases using output parameter'] = true
| |
| end
| |
| end | | end |
|
| |
|
Line 327: |
Line 246: |
| local out = obj:getOutput() | | local out = obj:getOutput() |
| -- Remove the random parts from strip markers. | | -- Remove the random parts from strip markers. |
| out = out:gsub('(\127\'"`UNIQ.-)%-%x+%-(QINU`"\'\127)', '%1%2') | | out = out:gsub('(%cUNIQ).-(QINU%c)', '%1%2') |
| return out | | return out |
| end | | end |
Line 341: |
Line 260: |
|
| |
|
| function TestCase:makeCollapsible(s) | | function TestCase:makeCollapsible(s) |
| local title = self.options.title or self.templates[1]:makeHeader()
| |
| if self.options.titlecode then
| |
| title = self.templates[1]:getInvocation('kbd')
| |
| end
| |
| local isEqual = self:templateOutputIsEqual() | | local isEqual = self:templateOutputIsEqual() |
| local root = mw.html.create('table') | | local root = mw.html.create('table') |
| if self.options.wantdiff then
| |
| root | | root |
| :addClass('mw-collapsible') | | :addClass('collapsible') |
| if self.options.notcollapsed == false then
| | :addClass(isEqual and 'collapsed' or nil) |
| root | |
| :addClass('mw-collapsed')
| |
| end
| |
| root
| |
| :css('background-color', 'transparent')
| |
| :css('width', '100%')
| |
| :css('border', 'solid silver 1px')
| |
| :tag('tr')
| |
| :tag('th')
| |
| :css('background-color', isEqual and 'yellow' or '#90a8ee')
| |
| :wikitext(title)
| |
| :done()
| |
| :done()
| |
| :tag('tr')
| |
| :tag('td')
| |
| :newline()
| |
| :wikitext(s)
| |
| :newline()
| |
| else
| |
| root
| |
| :addClass('mw-collapsible')
| |
| if self.options.notcollapsed == false then
| |
| root
| |
| :addClass('mw-collapsed')
| |
| end
| |
| if self.options.notcollapsed ~= true or false then
| |
| root
| |
| :addClass(isEqual and 'mw-collapsed' or nil)
| |
| end
| |
| root
| |
| :css('background-color', 'transparent') | | :css('background-color', 'transparent') |
| :css('width', '100%') | | :css('width', '100%') |
Line 387: |
Line 271: |
| :tag('th') | | :tag('th') |
| :css('background-color', isEqual and 'lightgreen' or 'yellow') | | :css('background-color', isEqual and 'lightgreen' or 'yellow') |
| :wikitext(title) | | :wikitext(self.options.title or self.templates[1]:makeHeading()) |
| :done() | | :done() |
| :done() | | :done() |
| :tag('tr') | | :tag('tr') |
| :tag('td') | | :tag('td') |
| :newline()
| |
| :wikitext(s) | | :wikitext(s) |
| :newline()
| |
| end
| |
| return tostring(root) | | return tostring(root) |
| end | | end |
Line 408: |
Line 289: |
|
| |
|
| local tableroot = root:tag('table') | | local tableroot = root:tag('table') |
| | tableroot |
| | :addClass(self.options.class) |
| | :cssText(self.options.style) |
| | :tag('caption') |
| | :wikitext(self.options.caption or self:message('columns-header')) |
|
| |
|
| if self.options.showheader then | | -- Headings |
| -- Caption
| | local headingRow = tableroot:tag('tr') |
| if self.options.showcaption then
| | if self.options.rowheader then |
| tableroot
| | -- rowheader is correct here. We need to add another th cell if |
| :addClass(self.options.class)
| | -- rowheader is set further down, even if heading0 is missing. |
| :cssText(self.options.style)
| | headingRow:tag('th'):wikitext(self.options.heading0) |
| :tag('caption')
| | end |
| :wikitext(self.options.caption or self:message('columns-header'))
| | local width |
| end
| | if #self.templates > 0 then |
| | | width = tostring(math.floor(100 / #self.templates)) .. '%' |
| -- Headers
| | else |
| local headerRow = tableroot:tag('tr')
| | width = '100%' |
| if self.options.rowheader then
| | end |
| -- rowheader is correct here. We need to add another th cell if
| | for i, obj in ipairs(self.templates) do |
| -- rowheader is set further down, even if heading0 is missing.
| | headingRow |
| headerRow:tag('th'):wikitext(self.options.heading0)
| | :tag('th') |
| end
| | :css('width', width) |
| local width
| | :wikitext(obj:makeHeading()) |
| if #self.templates > 0 then
| |
| width = tostring(math.floor(100 / #self.templates)) .. '%'
| |
| else
| |
| width = '100%'
| |
| end
| |
| for i, obj in ipairs(self.templates) do
| |
| headerRow | |
| :tag('th')
| |
| :css('width', width)
| |
| :wikitext(obj:makeHeader())
| |
| end
| |
| end | | end |
|
| |
|
Line 450: |
Line 325: |
| -- Template output | | -- Template output |
| for i, obj in ipairs(self.templates) do | | for i, obj in ipairs(self.templates) do |
| if self.options.output == 'nowiki+' then | | dataRow:tag('td') |
| dataRow:tag('td')
| | :newline() |
| :newline()
| | :wikitext(self:getTemplateOutput(obj)) |
| :wikitext(self.options.before)
| | :wikitext(self.options.after) |
| :wikitext(self:getTemplateOutput(obj))
| |
| :wikitext(self.options.after)
| |
| :wikitext('<pre style="white-space: pre-wrap;">')
| |
| :wikitext(mw.text.nowiki(self.options.before or ""))
| |
| :wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
| |
| :wikitext(mw.text.nowiki(self.options.after or ""))
| |
| :wikitext('</pre>')
| |
| elseif self.options.output == 'nowiki' then
| |
| dataRow:tag('td') | |
| :newline()
| |
| :wikitext(mw.text.nowiki(self.options.before or ""))
| |
| :wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
| |
| :wikitext(mw.text.nowiki(self.options.after or ""))
| |
| else
| |
| dataRow:tag('td') | |
| :newline()
| |
| :wikitext(self.options.before)
| |
| :wikitext(self:getTemplateOutput(obj))
| |
| :wikitext(self.options.after)
| |
| end
| |
| end | | end |
| | | |
Line 499: |
Line 354: |
|
| |
|
| for _, obj in ipairs(self.templates) do | | for _, obj in ipairs(self.templates) do |
| local dataRow = tableroot:tag('tr')
| | -- Build the row HTML |
|
| | tableroot |
| -- Header | | :tag('tr') |
| if self.options.showheader then | | :tag('td') |
| if self.options.format == 'tablerows' then | |
| dataRow:tag('th')
| |
| :attr('scope', 'row')
| |
| :css('vertical-align', 'top')
| |
| :css('text-align', 'left')
| |
| :wikitext(obj:makeHeader())
| |
| dataRow:tag('td')
| |
| :css('vertical-align', 'top')
| |
| :css('padding', '0 1em')
| |
| :wikitext('→')
| |
| else
| |
| dataRow:tag('td') | |
| :css('text-align', 'center') | | :css('text-align', 'center') |
| :css('font-weight', 'bold') | | :css('font-weight', 'bold') |
| :wikitext(obj:makeHeader()) | | :wikitext(obj:makeHeading()) |
| dataRow = tableroot:tag('tr')
| | :done() |
| end
| | :done() |
| end
| | :tag('tr') |
|
| | :tag('td') |
| -- Template output
| | :newline() |
| if self.options.output == 'nowiki+' then
| | :wikitext(self:getTemplateOutput(obj)) |
| dataRow:tag('td')
| |
| :newline() | |
| :wikitext(self:getTemplateOutput(obj))
| |
| :wikitext('<pre style="white-space: pre-wrap;">')
| |
| :wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
| |
| :wikitext('</pre>')
| |
| elseif self.options.output == 'nowiki' then
| |
| dataRow:tag('td') | |
| :newline() | |
| :wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
| |
| else
| |
| dataRow:tag('td')
| |
| :newline()
| |
| :wikitext(self:getTemplateOutput(obj))
| |
| end
| |
| end | | end |
|
| |
| return tostring(root)
| |
| end
| |
|
| |
| function TestCase:renderInline()
| |
| local arrow = mw.language.getContentLanguage():getArrow('forwards')
| |
| local ret = {}
| |
| for i, obj in ipairs(self.templates) do
| |
| local line = {}
| |
| line[#line + 1] = self.options.prefix or '* '
| |
| if self.options.showcode then
| |
| line[#line + 1] = obj:getInvocation('code')
| |
| line[#line + 1] = ' '
| |
| line[#line + 1] = arrow
| |
| line[#line + 1] = ' '
| |
| end
| |
| if self.options.output == 'nowiki+' then
| |
| line[#line + 1] = self:getTemplateOutput(obj)
| |
| line[#line + 1] = '<pre style="white-space: pre-wrap;">'
| |
| line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj))
| |
| line[#line + 1] = '</pre>'
| |
| elseif self.options.output == 'nowiki' then
| |
| line[#line + 1] = mw.text.nowiki(self:getTemplateOutput(obj))
| |
| else
| |
| line[#line + 1] = self:getTemplateOutput(obj)
| |
| end
| |
| ret[#ret + 1] = table.concat(line)
| |
| end
| |
| if self.options.addline then
| |
| local line = {}
| |
| line[#line + 1] = self.options.prefix or '* '
| |
| line[#line + 1] = self.options.addline
| |
| ret[#ret + 1] = table.concat(line)
| |
| end
| |
| return table.concat(ret, '\n')
| |
| end
| |
|
| |
| function TestCase:renderCells()
| |
| local root = mw.html.create()
| |
| local dataRow = root:tag('tr')
| |
| dataRow
| |
| :css('vertical-align', 'top')
| |
| :addClass(self.options.class)
| |
| :cssText(self.options.style)
| |
|
| |
| -- Row header
| |
| if self.options.rowheader then
| |
| dataRow:tag('th')
| |
| :attr('scope', 'row')
| |
| :newline()
| |
| :wikitext(self.options.rowheader or self:message('row-header'))
| |
| end
| |
| -- Caption
| |
| if self.options.showcaption then
| |
| dataRow:tag('th')
| |
| :attr('scope', 'row')
| |
| :newline()
| |
| :wikitext(self.options.caption or self:message('columns-header'))
| |
| end
| |
|
| |
| -- Show code
| |
| if self.options.showcode then
| |
| dataRow:tag('td')
| |
| :newline()
| |
| :wikitext(self:getInvocation('code'))
| |
| end
| |
|
| |
| -- Template output
| |
| for i, obj in ipairs(self.templates) do
| |
| if self.options.output == 'nowiki+' then
| |
| dataRow:tag('td')
| |
| :newline()
| |
| :wikitext(self.options.before)
| |
| :wikitext(self:getTemplateOutput(obj))
| |
| :wikitext(self.options.after)
| |
| :wikitext('<pre style="white-space: pre-wrap;">')
| |
| :wikitext(mw.text.nowiki(self.options.before or ""))
| |
| :wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
| |
| :wikitext(mw.text.nowiki(self.options.after or ""))
| |
| :wikitext('</pre>')
| |
| elseif self.options.output == 'nowiki' then
| |
| dataRow:tag('td')
| |
| :newline()
| |
| :wikitext(mw.text.nowiki(self.options.before or ""))
| |
| :wikitext(mw.text.nowiki(self:getTemplateOutput(obj)))
| |
| :wikitext(mw.text.nowiki(self.options.after or ""))
| |
| else
| |
| dataRow:tag('td')
| |
| :newline()
| |
| :wikitext(self.options.before)
| |
| :wikitext(self:getTemplateOutput(obj))
| |
| :wikitext(self.options.after)
| |
| end
| |
| end
| |
|
| |
|
| |
|
| return tostring(root) | | return tostring(root) |
Line 646: |
Line 379: |
| for i, obj in ipairs(self.templates) do | | for i, obj in ipairs(self.templates) do |
| ret[#ret + 1] = '<div style="clear: both;"></div>' | | ret[#ret + 1] = '<div style="clear: both;"></div>' |
| if self.options.showheader then | | ret[#ret + 1] = obj:makeBraceLink() |
| ret[#ret + 1] = obj:makeHeader()
| | ret[#ret + 1] = self:getTemplateOutput(obj) |
| end
| |
| if self.options.output == 'nowiki+' then
| |
| ret[#ret + 1] = self:getTemplateOutput(obj) .. '<pre style="white-space: pre-wrap;">' .. mw.text.nowiki(self:getTemplateOutput(obj)) .. '</pre>'
| |
| elseif self.options.output == 'nowiki' then
| |
| ret[#ret + 1] = mw.text.nowiki(self:getTemplateOutput(obj))
| |
| else | |
| ret[#ret + 1] = self:getTemplateOutput(obj)
| |
| end
| |
| end | | end |
| return table.concat(ret, '\n\n') | | return table.concat(ret, '\n\n') |
Line 666: |
Line 391: |
| if self.options.collapsible then | | if self.options.collapsible then |
| ret = self:makeCollapsible(ret) | | ret = self:makeCollapsible(ret) |
| end
| |
| for cat in pairs(self.categories) do
| |
| ret = ret .. string.format('[[Category:%s]]', cat)
| |
| end | | end |
| return ret | | return ret |
Line 696: |
Line 418: |
| end | | end |
|
| |
|
| function NowikiInvocation:getInvocation(options) | | function NowikiInvocation:getInvocation(template) |
| local template = options.template:gsub('%%', '%%%%') -- Escape "%" with "%%" | | template = template:gsub('%%', '%%%%') -- Escape "%" with "%%" |
| local invocation, count = self.invocation:gsub( | | local invocation, count = self.invocation:gsub( |
| self.cfg.templateNameMagicWordPattern, | | self.cfg.templateNameMagicWordPattern, |
| template | | template |
| ) | | ) |
| if options.requireMagicWord ~= false and count < 1 then | | if count < 1 then |
| error(self:message( | | error(self:message( |
| 'nowiki-magic-word-error', | | 'nowiki-magic-word-error', |
Line 711: |
Line 433: |
| end | | end |
|
| |
|
| function NowikiInvocation:getOutput(options) | | function NowikiInvocation:getOutput(template) |
| local invocation = self:getInvocation(options) | | local invocation = self:getInvocation(template) |
| return mw.getCurrentFrame():preprocess(invocation) | | return mw.getCurrentFrame():preprocess(invocation) |
| end | | end |
Line 732: |
Line 454: |
| end | | end |
|
| |
|
| function TableInvocation:getInvocation(options) | | function TableInvocation:getInvocation(template) |
| if self.code then | | if self.code then |
| local nowikiObj = NowikiInvocation.new(self.code, self.cfg) | | local nowikiObj = NowikiInvocation(self.code, self.cfg) |
| return nowikiObj:getInvocation(options) | | return nowikiObj:getInvocation(template) |
| else | | else |
| return require('Module:Template invocation').invocation( | | return require('Module:Template invocation').invocation( |
| options.template, | | template, |
| self.invokeArgs | | self.invokeArgs |
| ) | | ) |
Line 744: |
Line 466: |
| end | | end |
|
| |
|
| function TableInvocation:getOutput(options) | | function TableInvocation:getOutput(template) |
| if (options.template:sub(1, 7) == '#invoke') then
| |
| local moduleCall = mw.text.split(options.template, '|', true)
| |
| local args = mw.clone(self.invokeArgs)
| |
| table.insert(args, 1, moduleCall[2])
| |
| return mw.getCurrentFrame():callParserFunction(moduleCall[1], args)
| |
| end
| |
| return mw.getCurrentFrame():expandTemplate{ | | return mw.getCurrentFrame():expandTemplate{ |
| title = options.template, | | title = template, |
| args = self.invokeArgs | | args = self.invokeArgs |
| } | | } |
Line 758: |
Line 474: |
|
| |
|
| ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
| -- Bridge functions | | -- Exports |
| --
| |
| -- These functions translate template arguments into forms that can be accepted
| |
| -- by the different classes, and return the results.
| |
| ------------------------------------------------------------------------------- | | ------------------------------------------------------------------------------- |
|
| |
|
| local bridge = {} | | local p = {} |
|
| |
|
| function bridge.table(args, cfg) | | function p.table(args, cfg) |
| cfg = cfg or mw.loadData(DATA_MODULE) | | cfg = cfg or mw.loadData(DATA_MODULE) |
|
| |
|
Line 795: |
Line 508: |
| end | | end |
|
| |
|
| function bridge.nowiki(args, cfg) | | function p.nowiki(args, cfg) |
| cfg = cfg or mw.loadData(DATA_MODULE) | | cfg = cfg or mw.loadData(DATA_MODULE) |
|
| |
|
| local code = args.code or args[1]
| | local invocationObj = NowikiInvocation.new(args.code, cfg) |
| local invocationObj = NowikiInvocation.new(code, cfg) | |
| args.code = nil | | args.code = nil |
| args[1] = nil
| |
| -- Assume we want to see the code as we already passed it in. | | -- Assume we want to see the code as we already passed it in. |
| args.showcode = args.showcode or true | | args.showcode = args.showcode or true |
Line 807: |
Line 518: |
| return tostring(testCaseObj) | | return tostring(testCaseObj) |
| end | | end |
|
| |
| -------------------------------------------------------------------------------
| |
| -- Exports
| |
| -------------------------------------------------------------------------------
| |
|
| |
| local p = {}
| |
|
| |
|
| function p.main(frame, cfg) | | function p.main(frame, cfg) |
Line 847: |
Line 552: |
| end | | end |
|
| |
|
| return bridge[func](args, cfg) | | return p[func](args, cfg) |
| end | | end |
|
| |
|