diff --git a/Lua banner/main.lua b/Lua banner/main.lua new file mode 100644 index 0000000..c654761 --- /dev/null +++ b/Lua banner/main.lua @@ -0,0 +1,128 @@ +-- This module implements the {{lua}} template. +local yesno = require('Module:Yesno') +local mList = require('Module:List') +local mTableTools = require('Module:TableTools') +local mMessageBox = require('Module:Message box') + +local p = {} + +function p.main(frame) + local origArgs = frame:getParent().args + local args = {} + for k, v in pairs(origArgs) do + v = v:match('^%s*(.-)%s*$') + if v ~= '' then + args[k] = v + end + end + return p._main(args) +end + +function p._main(args) + local modules = mTableTools.compressSparseArray(args) + local box = p.renderBox(modules) + local trackingCategories = p.renderTrackingCategories(args, modules) + return box .. trackingCategories +end + +function p.renderBox(modules) + local boxArgs = {} + if #modules < 1 then + boxArgs.text = 'Error: no modules specified' + else + local moduleLinks = {} + for i, module in ipairs(modules) do + moduleLinks[i] = string.format('[[:%s]]', module) + local maybeSandbox = mw.title.new(module .. '/sandbox') + if maybeSandbox.exists then + moduleLinks[i] = moduleLinks[i] .. string.format(' ([[:%s|sandbox]])', maybeSandbox.fullText) + end + end + local moduleList = mList.makeList('bulleted', moduleLinks) + local title = mw.title.getCurrentTitle() + if title.subpageText == "doc" then + title = title.basePageTitle + end + if title.contentModel == "Scribunto" then + boxArgs.text = 'This module depends on the following other modules:' .. moduleList + else + boxArgs.text = 'This template uses [[BKDatabase:Lua|Lua]]:\n' .. moduleList + end + end + boxArgs.type = 'notice' + boxArgs.small = true + boxArgs.image = '[[File:Lua-Logo.svg|30px|alt=|link=]]' + return mMessageBox.main('mbox', boxArgs) +end + +function p.renderTrackingCategories(args, modules, titleObj) + if yesno(args.nocat) then + return '' + end + + local cats = {} + + -- Error category + if #modules < 1 then + cats[#cats + 1] = 'Lua templates with errors' + end + + -- Lua templates category + titleObj = titleObj or mw.title.getCurrentTitle() + local subpageBlacklist = { + doc = true, + sandbox = true, + sandbox2 = true, + testcases = true + } + if not subpageBlacklist[titleObj.subpageText] then + local protCatName + if titleObj.namespace == 10 then + local category = args.category + if not category then + local categories = { + ['Module:String'] = 'Templates based on the String Lua module', + ['Module:Math'] = 'Templates based on the Math Lua module', + ['Module:BaseConvert'] = 'Templates based on the BaseConvert Lua module', + ['Module:Citation/CS1'] = 'Templates based on the Citation/CS1 Lua module' + } + category = modules[1] and categories[modules[1]] + category = category or 'Lua-based templates' + end + cats[#cats + 1] = category + protCatName = "Templates using under-protected Lua modules" + elseif titleObj.namespace == 828 then + protCatName = "Modules depending on under-protected modules" + end + if not args.noprotcat and protCatName then + local protLevels = { + autoconfirmed = 1, + extendedconfirmed = 2, + templateeditor = 3, + sysop = 4 + } + local currentProt + if titleObj.id ~= 0 then + -- id is 0 (page does not exist) if am previewing before creating a template. + currentProt = titleObj.protectionLevels["edit"][1] + end + if currentProt == nil then currentProt = 0 else currentProt = protLevels[currentProt] end + for i, module in ipairs(modules) do + if module ~= "WP:libraryUtil" then + local moduleProt = mw.title.new(module).protectionLevels["edit"][1] + if moduleProt == nil then moduleProt = 0 else moduleProt = protLevels[moduleProt] end + if moduleProt < currentProt then + cats[#cats + 1] = protCatName + break + end + end + end + end + end + for i, cat in ipairs(cats) do + cats[i] = string.format('[[Category:%s]]', cat) + end + return table.concat(cats) +end + +return p diff --git a/Testcases/Includes.lua b/Testcases/Includes.lua new file mode 100644 index 0000000..faa4c57 --- /dev/null +++ b/Testcases/Includes.lua @@ -0,0 +1,30 @@ +-- Unit tests for [[Module:{{ROOTPAGENAME}}]]. Click talk page to run tests. +local p = require('Module:UnitTests') + +-- Example unit test. +function p:test_hello() + local includes = require('Module:Includes') + + -- These will return true + self:equals('includes({"a", "b", "c", "d"}, "b")', includes({"a", "b", "c", "d"}, "b"), true) + self:equals('includes({"a", "b", "c", "d"}, "b", 0)', includes({"a", "b", "c", "d"}, "b", 0), true) + self:equals('includes({"a", "b", "c", "d"}, "b", 1)', includes({"a", "b", "c", "d"}, "b", 1), true) + self:equals('includes({"a", "b", "c", "d"}, "b", 2)', includes({"a", "b", "c", "d"}, "b", 2), true) + self:equals('includes({"a", "b", "c", "d"}, "b", -3)', includes({"a", "b", "c", "d"}, "b", -3), true) + self:equals('includes({"a", "b", "c", "d"}, "b", -5)', includes({"a", "b", "c", "d"}, "b", -5), true) + self:equals('includes({[1] = "a",[100] = "b",[101] = "c"}, "b")', includes({[1] = "a",[100] = "b",[101] = "c"}, "b"), true) + self:equals('includes({[1] = "a",[2] = "b",[3] = "c"}, "b", 0)', includes({[1] = "a",[2] = "b",[3] = "c"}, "b", 0), true) + self:equals('includes({first = "a", second = "b", third = "c"}, "b")', includes({first = "a", second = "b", third = "c"}, "b"), true) + + --these will return false + self:equals('includes("b","b")', includes("b","b"), false) -- array is not a table + self:equals('includes({"a", "b", "c", "d"})', includes({"a", "b", "c", "d"}), false) -- value missing + self:equals('includes({"a", "b", "c", "d"}, "e")', includes({"a", "b", "c", "d"}, "e"), false) -- "e" is not in array + self:equals('includes({"a", "b", "c", "d"}, "b", 3)', includes({"a", "b", "c", "d"}, "b", 3), false) -- "b" is before position 3 + self:equals('includes({"a", "b", "c", "d"}, "b", 5)', includes({"a", "b", "c", "d"}, "b", 5), false) -- 5 is larger than #array + self:equals('includes({"a", "b", "c", "d"}, "b", -2)', includes({"a", "b", "c", "d"}, "b", -2), false) -- "b" is not in the last two positions + self:equals('includes({[1] = "a", [100] = "b", [101] = "c"}, "b", 0)', includes({[1] = "a", [100] = "b", [101] = "c"}, "b", 0), false) -- key 100 is non-consecutive + self:equals('includes({first = "a", second = "b", third = "c"}, "b", 0)', includes({first = "a", second = "b", third = "c"}, "b", 0), false) -- key "second" is not an integer +end + +return p diff --git a/Testcases/Infobox.lua b/Testcases/Infobox.lua new file mode 100644 index 0000000..9b660ff --- /dev/null +++ b/Testcases/Infobox.lua @@ -0,0 +1,43 @@ +-- Ví dụ các trường hợp kiểm thử đơn vị cho [[Mô đun:Infobox]]. Nhấn vào trang thảo luận để +-- chạy các trường hợp kiểm thử. +local p = require('Mô đun:UnitTests') + +function p:test_hello() + self:preprocess_equals_preprocess_many('{{infobox/sandbox', '}}', '{{Infobox', '}}', { + {[=[ + |label1 = Nhãn 1 + |data1 = Dữ liệu 1 + ]=]}, + }, {nowiki = 'yes'}) +end + +function p:test_ids() + self:preprocess_equals_preprocess_many('{{infobox/sandbox', '}}', '{{Infobox', '}}', { + {[=[ + |label2 = Nhãn 2 + |labelid2 = lable + |data2 = Dữ liệu 2 + |dataid2 = data + |rowid1 = row + |header1 = Đầu đề 1 + |headerid1 = header + ]=]}, + }, {nowiki = 'yes'}) +end + +function p:test_ids_name() + self:preprocess_equals_preprocess_many('{{infobox/sandbox', '}}', '{{Infobox', '}}', { + {[=[ + |name = qw er tz + |label2 = Nhãn 2 + |labelid2 = lable + |data2 = Dữ liệu 2 + |dataid2 = data + |rowid1 = row + |header1 = Đầu đề 1 + |headerid1 = header + ]=]}, + }, {nowiki = 'yes'}) +end + +return p diff --git a/Testcases/InfoboxImage.lua b/Testcases/InfoboxImage.lua new file mode 100644 index 0000000..bb7d304 --- /dev/null +++ b/Testcases/InfoboxImage.lua @@ -0,0 +1,109 @@ +-- Unit tests for [[Module:InfoboxImage]]. Click talk page to run tests. + +local p = require('Module:UnitTests') + +function p:test1_parameters_output() + self:preprocess_equals_preprocess_many('{{#invoke:InfoboxImage/sandbox |InfoboxImage |image=', '}}', '{{#invoke:InfoboxImage |InfoboxImage |image=', '}}', { + {'Small Sailboat Image.jpg |alt=Alt'}, + {'Small Sailboat Image.jpg |border=yes'}, + {'Small Sailboat Image.jpg |center=yes'}, + {'Small Sailboat Image.jpg |link=Link'}, + {'Small Sailboat Image.jpg |thumbtime=Thumbtime'}, + {'Small Sailboat Image.jpg |title=Title'}, + {'Small Sailboat Image.jpg |size=75'}, + {'Small Sailboat Image.jpg |size=200'}, + {'Small Sailboat Image.jpg |size=200|sizedefault=260|maxsize=275'}, + {'Small Sailboat Image.jpg |size=400|sizedefault=260|maxsize=275'}, + {'Small Sailboat Image.jpg |sizedefault=260|maxsize=275'}, + {'Small Sailboat Image.jpg |maxsize=275'}, + {'Small Sailboat Image.jpg |maxsize=275|sizedefault=frameless'}, + {'[[File:Small Sailboat Image.jpg]]'}, + {'Mustela erminea upright.jpg'}, + {'Mustela erminea upright.jpg |upright=1'}, + {'Mustela erminea upright.jpg |upright=yes'}, + {'Mustela erminea upright.jpg |upright=0.75'}, + {'Mustela erminea upright.jpg |upright=1.2'}, + {'Mustela erminea upright.jpg |upright=1|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1|maxsize=275|sizedefault=frameless'}, + {'Mustela erminea upright.jpg |upright=1|sizedefault=260|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1.5|sizedefault=260|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1|size=200|sizedefault=260|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1|size=|sizedefault=|maxsize='}, + {'Replace this image.svg |suppressplaceholder=no'}, + {'Replace this image.svg'}, + {'The Universal Magazine, Vol. XCV (July 1794).djvu |page=8'}, + {'[[File:Abbey Rd Studios.jpg|200px]]'}, + {'[[File:Abbey Rd Studios.jpg|thumb]]'}, + {'[[File:Abbey Rd Studios.jpg|thumb|caption]]'}, + {'Http-fakezarathustra.blogspot.com-2010-10-12 31.html http-fakezarathustra.blogspot.com-2010-10-22 31.html - panoramio.jpg'}, + {'Abbey Rd Studios.jpg|alt=http:test.com'}, + {'Abbey Rd Studios.jpg|alt=[http:test.com]'}, + {'Abbey Rd Studios.jpg|class=notpageimage'}, + }) +end + +function p:test2_parameters_nowiki() + self:preprocess_equals_preprocess_many('{{#invoke:InfoboxImage/sandbox |InfoboxImage |image=', '}}', '{{#invoke:InfoboxImage|InfoboxImage |image=', '}}', { + {'Small Sailboat Image.jpg |alt=Alt'}, + {'Small Sailboat Image.jpg |border=yes'}, + {'Small Sailboat Image.jpg |center=yes'}, + {'Small Sailboat Image.jpg |link=Link'}, + {'Small Sailboat Image.jpg |thumbtime=Thumbtime'}, + {'Small Sailboat Image.jpg |title=Title'}, + {'Small Sailboat Image.jpg |size=75'}, + {'Small Sailboat Image.jpg |size=200'}, + {'Small Sailboat Image.jpg |size=200|sizedefault=260|maxsize=275'}, + {'Small Sailboat Image.jpg |size=400|sizedefault=260|maxsize=275'}, + {'Small Sailboat Image.jpg |sizedefault=260|maxsize=275'}, + {'Small Sailboat Image.jpg |maxsize=275'}, + {'Small Sailboat Image.jpg |maxsize=275|sizedefault=frameless'}, + {'Small Sailboat Image.jpg |size=20%|sizedefault=10em'}, + {'[[File:Small Sailboat Image.jpg]]'}, + {'Mustela erminea upright.jpg'}, + {'Mustela erminea upright.jpg |upright=1'}, + {'Mustela erminea upright.jpg |upright=yes'}, + {'Mustela erminea upright.jpg |upright=0.75'}, + {'Mustela erminea upright.jpg |upright=1.2'}, + {'Mustela erminea upright.jpg |upright=1|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1|maxsize=275|sizedefault=frameless'}, + {'Mustela erminea upright.jpg |upright=1|sizedefault=260|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1.5|sizedefault=260|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1|size=200|sizedefault=260|maxsize=275'}, + {'Mustela erminea upright.jpg |upright=1|size=|sizedefault=|maxsize='}, + {'Replace this image.svg |suppressplaceholder=no'}, + {'Replace this image.svg'}, + {'The Universal Magazine, Vol. XCV (July 1794).djvu |page=8'}, + {'Http-fakezarathustra.blogspot.com-2010-10-12 31.html http-fakezarathustra.blogspot.com-2010-10-22 31.html - panoramio.jpg'}, + {'Abbey Rd Studios.jpg|alt=http:test.com'}, + {'Abbey Rd Studios.jpg|alt=[http:test.com]'}, + {'Abbey Rd Studios.jpg|class=notpageimage'}, + {'[[File:Abbey Rd Studios.jpg|200px]]'}, + {'[[File:Abbey Rd Studios.jpg|thumb]]'}, + {'[[File:Abbey Rd Studios.jpg|thumb|caption]]'}, + },{nowiki=1}) +end + +function p:test3_errors() + self:preprocess_equals_preprocess_many('{{#invoke:InfoboxImage/sandbox |InfoboxImage |image=', '}}', '{{#invoke:InfoboxImage|InfoboxImage |image=', '}}', { + {'Mustela erminea upright.jpg |size=1.2'}, + {'Mustela erminea upright.jpg |size=300x'}, + {'Mustela erminea upright.jpg |sizedefault=300x | maxsize=200'}, + {'Mustela erminea upright.jpg |size=300 | maxsize=200x'}, + {'Mustela erminea upright.jpg |sizedefault=145 | maxsize=300x'}, + {'http:test.com'}, + {'[http:test.com]'}, + {'[[http:test.com]]'}, + {'https:test.com'}, + {'[https:test.com]'}, + {'[[https:test.com]]'}, + },{nowiki=1}) +end + +function p:test4_stripmarkers() + self:preprocess_equals_preprocess( + '{{#invoke:InfoboxImage/sandbox |InfoboxImage |image={{multiple image | width = 60 | image1 = Yellow card.svg | image2 = Red card.svg}}}}', + '{{#invoke:InfoboxImage |InfoboxImage |image={{multiple image | width = 60 | image1 = Yellow card.svg | image2 = Red card.svg}}}}', + {stripmarker=1}) +end + +return p diff --git a/Uses TemplateStyles/config.lua b/Uses TemplateStyles/config.lua new file mode 100644 index 0000000..3a34837 --- /dev/null +++ b/Uses TemplateStyles/config.lua @@ -0,0 +1,58 @@ +local cfg = {} -- Don’t touch this line. + +-- Subpage blacklist: these subpages will not be categorized (except for the +-- error category, which is always added if there is an error). +-- For example “Template:Foo/doc” matches the `doc = true` rule, so it will have +-- no categories. “Template:Foo” and “Template:Foo/documentation” match no rules, +-- so they *will* have categories. All rules should be in the +-- [''] = true, +-- format. +cfg['subpage_blacklist'] = { + ['doc'] = true, + ['sandbox'] = true, + ['sandbox2'] = true, + ['testcases'] = true, +} + +-- Sandbox title: if the stylesheet’s title is