diff --git a/Script doc auto/Gadgets.lua b/Script doc auto/Gadgets.lua new file mode 100644 index 0000000..e34bdbd --- /dev/null +++ b/Script doc auto/Gadgets.lua @@ -0,0 +1,86 @@ +local p = {} + +p.parse = function() + local text = mw.title.new('MediaWiki:Gadgets-definition'):getContent() + local lines = mw.text.split(text, '\n', false) + + local repo = {} + for _, line in ipairs(lines) do + if line:sub(1, 1) == '*' then + local name, options, pages = p.parse_line(line) + if name and #pages ~= 0 then + repo[name] = { options = options, pages = pages } + end + end + end + return repo +end + +p.parse_line = function(def) + local pattern = "^%*%s*(.+)%s*(%b[])%s*(.-)$" + local name, opts, pageList = string.match(def, pattern) + + if name then + name = mw.text.trim(name) + end + + -- Process options string into a Lua table + local options = {} + if opts then + -- Extracting the options without square brackets and trimming spaces + opts = opts:sub(2, -2):gsub("%s+", "") + + for pair in opts:gmatch("%s*([^|]+)%s*|?") do + local key, value = pair:match("%s*([^=]+)%s*=%s*([^=|]+)%s*") + if key and value then + options[key:match("%s*(.-)%s*$")] = value:match("^%s*(.-)%s*$") + else + key = pair:match("%s*(.-)%s*$") + options[key] = true + end + end + end + + -- Process page list into an array + local pages = {} + if pageList then + for page in pageList:gmatch("[^|]+") do + table.insert(pages, mw.text.trim(page)) + end + end + return name, options, pages +end + +p.get_type = function(def) + if def.options.type == 'general' or def.options.type == 'styles' then + return def.options.type + end + if def.options.dependencies ~= nil then + return 'general' + end + for _, page in ipairs(def.pages) do + if not string.match(page, '%.css$') then + return 'general' + end + end + return 'styles' +end + +p.get_usage = function(name) + name = name:gsub("_", " ") + + local success, tabData = pcall(mw.ext.data.get, 'GadgetUsage.tab') + if not success or not tabData or not tabData.data then + return -1 + end + + for _, row in ipairs(tabData.data) do + if row[1] == name then + return tonumber(row[2]) or -1 + end + end + + return -1 +end + +return p \ No newline at end of file diff --git a/Script doc auto/main.lua b/Script doc auto/main.lua new file mode 100644 index 0000000..a2c9260 --- /dev/null +++ b/Script doc auto/main.lua @@ -0,0 +1,148 @@ +local MessageBox = require('Module:Message box') +local Gadgets = require('Module:Gadgets') +local Arguments = require('Module:Arguments') +local TableTools = require('Module:TableTools') + +local p = {} + +p.main = function(frame) + local args = Arguments.getArgs(frame) + return p.core(args.page or mw.title.getCurrentTitle().fullText) +end + +p.core = function(page) + local text = '' + + local content = mw.title.new(page).content + if content then + local result = content:match("/%* ({{mfd.-}})") + if result then + text = text .. mw.getCurrentFrame():preprocess(result) + end + end + + local len = page:len() + if len < 4 then + -- Too short page name, do nothing more + return text + end + + return p.makeMessage(page) +end + +local skins = TableTools.listToSet({ + 'common', 'vector-2022', 'vector', 'timeless', 'minerva', 'monobook', 'modern', 'cologneblue', 'citizen' +}) + +p.gadget_text = function(name, repo) + local lang = mw.getContentLanguage() + local options = repo[name].options + local dependents = {} + if options.hidden ~= nil then + -- Find dependents + for n, c in pairs(repo) do + local deps = c.options.dependencies and + TableTools.listToSet(mw.text.split(c.options.dependencies, ',', false)) or {} + local peers = c.options.peers and + TableTools.listToSet(mw.text.split(c.options.peers, ',', false)) or {} + if deps['ext.gadget.'..name] ~= nil or peers[name] ~= nil then + table.insert(dependents, '[[Special:Gadgets#gadget-'..n..'|'..n..']]') + end + end + end + local usage = Gadgets.get_usage(name) + if usage == -1 then + usage = "an unknown number of" + else + usage = lang:formatNum(usage) + end + return 'This page is loaded as a part of the ' .. + '[[Special:Gadgets#gadget-'..name..'|'..name..']] gadget' .. + (options.hidden ~= nil and ', a hidden gadget'.. + (#dependents > 0 and ' used by '..mw.text.listToText(dependents)..'.' or '.') or + (options.default ~= nil and ', which is enabled by default.' or + (', used by '..usage..' users. '))) +end + +p.makeMessage = function(page) + local pageparts = mw.text.split(page, '.', true) + local pagetype = '.' .. pageparts[#pageparts] + + local pagetypes = TableTools.listToSet({ + '.js', '.css', '.json', '.vue' + }) + + if #pageparts<2 or pagetypes[pagetype] == nil then + return '' + end + + local function listSisters(title, intro) + local output = {intro} + for sistertype in pairs(pagetypes) do + if sistertype ~= pagetype then + local sisterpage = mw.title.new(title .. sistertype) + if sisterpage.exists then + table.insert(output, + 'an accompanying '..sistertype..' page at [['..sisterpage.fullText..']]' + ) + end + end + end + --listToText with Oxford commas + return mw.text.listToText(output, ', ', (#output > 2) and ', and ' or ' and ') .. '.' + end + + local text = '' + local basepage = mw.title.new(page:sub(0, -1 * (#pagetype + 1))) + + if basepage.namespace == 2 then + if skins[basepage.subpageText] ~= nil and (pagetype == '.js' or pagetype == '.css') then + -- We are on a user skin file + local sistertype = (pagetype == '.js') and '.css' or '.js' + local sisterpage = mw.title.new(basepage.fullText .. sistertype) + text = 'The accompanying '..sistertype..' page for this skin '.. + (sisterpage.exists and 'is' or 'can be added')..' at [['..sisterpage.fullText..']].' + else + -- We are on some script page, not a user skin file + if basepage.exists then + text = listSisters(basepage.fullText, 'This user script seems to have a documentation page at [['..basepage.fullText..']]') + else + text = listSisters(basepage.fullText) + text = 'Documentation for this user script can be added at [['..basepage.fullText..']]' .. + ((#text > 1) and '. This user script seems to have ' or '') .. + text + end + end + elseif basepage.namespace == 8 then + if basepage.text:find('^Gadget-') ~= nil then + local gadgetRepo = Gadgets.parse() + local shortName = basepage.text:gsub('^Gadget%-', '') .. pagetype + for name, config in pairs(gadgetRepo) do + if TableTools.inArray(config.pages, shortName) then + text = text .. p.gadget_text(name, gadgetRepo) + end + end + if text ~= '' then + local sisterText = listSisters(basepage.fullText) + text = text .. + ((#sisterText > 1) and (' There seems to be ' .. sisterText) or '') .. + '
' + end + end + end + + if text ~= '' then + return mw.getCurrentFrame():extensionTag{ + name = 'templatestyles', args = { src = 'Module:Script doc auto/styles.css' } + } .. MessageBox.main('fmbox', { + class = 'script-doc-auto-box', + id = 'mw-script-doc', + type = 'system', + image = '[[File:Ledger_open_button.webp|43x40px|link=]]', + text = text + }) + end + return '' +end + +return p \ No newline at end of file diff --git a/Script doc auto/styles.css b/Script doc auto/styles.css new file mode 100644 index 0000000..e814811 --- /dev/null +++ b/Script doc auto/styles.css @@ -0,0 +1,18 @@ +/* {{pp-template|small=yes}} */ +/* colors same as [[Module:Documentation/styles.css]] */ +.script-doc-auto-box.script-doc-auto-box { + background: #061016; +} + +@media screen { + html.skin-theme-clientpref-night .script-doc-auto-box.script-doc-auto-box { + background-color: #061016; + } +} + + +@media screen and ( prefers-color-scheme: dark) { + html.skin-theme-clientpref-os .script-doc-auto-box.script-doc-auto-box { + background-color: #061016; + } +} \ No newline at end of file