Module:ModularCSS
Jump to navigation
Jump to search
Documentation for this module may be created at Module:ModularCSS/doc
--| Module:ModularCSS (v1.5.0)
-- v1.5.0 - Retrieves MediaWiki messages through mw.message
--by "The JoTS"
--- Lua module that simplifies clutter on wiki's CSS pages
--- by dynamically generating modular CSS code.
-- e.g. CSS that changes the link color of every wiki admin
-- e.g. Infoboxes that change color on a page by page basis
-- <nowiki>
-- [==[ Module Start ]==] ------
local module = {}
local imports = {}
local configs = {}
local localUrl = mw.uri.localUrl
-- Helper functions
local function parse(pgName)
-- Avoid incrementing expensive function count
-- if using a special page, return empty table
if pgName:sub(1,8):lower() == "special:" then return {} end
-- Find cached parsed results and return
if configs[pgName] then return configs[pgName] end
-- BEGIN PARSING TASK
-- Find page and get content
local page
if pgName:sub(1,10):lower() == "mediawiki:" then
page = mw.message.new(pgName:sub(11))
assert(page:exists(),
'The config page "' .. pgName .. '" does not exist on this wiki.')
page = tostring(page) .. '\n'
else
page = mw.title.new(pgName)
assert(page, "Invalid page title!")
assert(page.exists,
'The config page "' .. pgName .. '" does not exist on this wiki.')
page = (page:getContent() or "") .. '\n'
end
-- Flags... and stuff
local parsed = {}
local parent_obj = parsed
local last_index
local curr_lvl = 1
-- Parse bulleted list
for ast,val in page:gmatch("(\*+)%s*(.-)\n") do
local lvl = #ast
local key, true_self = (val:gsub(" ","_")), (val:gsub("_"," "))
if lvl > curr_lvl then
parent_obj = parent_obj[last_index]
elseif lvl < curr_lvl then
parent_obj = parent_obj.parent
end
assert(not parent_obj[key], "Duplicate value in the same bullet level!")
parent_obj[key] = setmetatable({},{
__index = {
parent = parent_obj,
self = true_self, -- standardized, unadulterated by underscores; human readable ver.
getLocalUrl = function(t, raw)
return tostring(localUrl(t.self))
:gsub("%%", {[raw and '' or "%"] = "%%"}) -- this is stupid
end,
getValue = function(t)
return next(t) and next(t).self
end
}
})
last_index = key
curr_lvl = lvl
end
-- cache
configs[pgName] = parsed;
-- return newly parsed results
return parsed
end
-- Invoked wikitext functions
local function _render()
assert(#imports > 0, "No ModularCSS modules were imported!")
local renderedCSS = ""
for modNum,cssMod in pairs(imports) do
local err_header = "CSS Module #" .. modNum .. ": "
-- CSS module format errors
assert(cssMod.page and type(cssMod.page) == "string",
err_header .. '"page" string provided in module is invalid.')
assert(cssMod.main and type(cssMod.main) == "function",
err_header .. '"main" function provided in module is invalid.')
local success,css_vars = pcall(parse, cssMod.page)
assert(success, err_header .. tostring(css_vars))
local success,modCompiledCSS = pcall(cssMod.main, css_vars)
renderedCSS = renderedCSS
.. assert(
assert(success, modCompiledCSS) and modCompiledCSS,
"The CSS module did not return a value."
)
end
return renderedCSS
end
local render = function(frame)
local success,compiled = pcall(_render)
if (not success) then return "/*" .. compiled .. "*/" end
return frame:preprocess('/*<syntaxhighlight lang="css" enclose="div" '
.. 'style="overflow:auto;">*/'
.. compiled
.. '/*</syntaxhighlight>*/')
end
-- Meta-module functions
local function import_wrap(lax)
return function(moduleName)
assert(type(moduleName) == "string", "Invalid module request! Not a string.")
local success,reqModule = pcall(require, moduleName)
assert(success, "Non-existent module requested: " .. moduleName)
table.insert(imports, reqModule)
reqModule.page = lax and reqModule.public_page or reqModule.page
return module
end
end
local import = import_wrap(false)
local importlax = import_wrap(true)
-- en
module.import = import
module.render = render
module.importlax = importlax
return module