local p = -------------------------------------Code from other people-------------------------------------
TableTools = require("Module:TableTools")
--https://stackoverflow.com/a/1283608--All stack overflow code is CC BY-SA 3.0local function tableMerge(t1, t2) for k,v in pairs(t2) do if type(v)
"table" then _tableMerge(t1[k] or, t2[k] or) else t1[k] = v end else t1[k] = v end end return t1end
--This function is public domain. See http://lua-users.org/wiki/OrderedTable--Modified to be able to accept argslocal function Ordered(t) --nextkey and firstkey are used as markers; nextkey[firstkey] is --the first key in the table, and nextkey[nextkey] is the last key. --nextkey[nextkey[nextkey]] should always be nil.
local key2val, nextkey, firstkey =,, nextkey[nextkey] = firstkey local function onext(self, key) while key ~= nil do key = nextkey[key] local val = self[key] if val ~= nil then return key, val end end end -- To save on tables, we use firstkey for the (customised) -- metatable; this line is just for documentation local selfmeta = firstkey -- record the nextkey table, for routines lacking the closure selfmeta.__nextkey = nextkey -- setting a new key (might) require adding the key to the chain function selfmeta:__newindex(key, val) rawset(self, key, val) if nextkey[key]
p.Ordered = Ordered
------------------------------------------Code from me------------------------------------------
--metatable of mw.htmlp.htmlMeta = getmetatable(mw.html.create)
p.orderedMeta = getmetatable(p.Ordered)
function p.filter(tabl, typ) local typeCheck = (type(typ)
"table" and getmetatable) or error("Invalid type!") local out = for k,v in pairs(tabl) do if typeCheck(v)
--------------------------------
--an HTML Elementlocal Element =
Element.__index = Element
--Create a new Elementfunction Element.new(type) o = setmetatable(Element) o.type = type o.children = o.style = Ordered o.classes = return oend
--Add Element or mw.html as childfunction Element:add(child) if getmetatable(child)
--Add string as childfunction Element:wikitext(child) if type(child) ~= "string" then error("Inavlid child!") end table.insert(self.children, child) return selfend
--create a new Element then add itfunction Element:tag(name) elem = Element.new(name) return self:add(elem)end
--add a newline (br)function Element:newline self:tag("br") return selfend
--add a css propertyfunction Element:css(k, v) if type(k)
"string" and type(v)
--add classesfunction Element:class(class) if type(class)
"string" then table.insert(self.classes, class) else error("Invalid class type!") end return selfend
--set the idfunction Element:setId(id) if type(id) ~= "string" then error("Id must be string!") end self.id = id return selfend
--returns parent. used for function chainingfunction Element:done return self.parent or selfend
--returns the root Elementfunction Element:allDone local parent = self.parent if parent
--turn this Element into an mw.html objectfunction Element:bake local root = mw.html.create(self.type):css(self.style) for _,class in ipairs(self.classes) do root:addClass(class) end for _, child in ipairs(self.children) do if getmetatable(child)
htmlMeta then --do not need to bake mw.html root:node(child) elseif type(child)
--bakes the root Elementfunction Element:bakeAll return self:allDone:bakeend
--wip dont usefunction Element:stylesheet(css) for _,c in ipairs(css) do for _,s in ipairs(c.selectors) do if s:check(self) then self:css(c.properties) break end end end for _,child in pairs(p.filter(self.children, Element)) do child:stylesheet(css) end return selfend
--------------------------------
local Selector = --selections ordered roughly by price, cheapest to most expensive --basic selections-- yes - Makes the selector always be true (*) id - Element must have this id (#id) type - Element must be of this type (type) class - Element must have all these classes (.class1.class2 etc) --combinator selections-- directParent- Element must have its parent element match this selector (parentElement > element) parent - Element must be inside an element matching this selector (parentElement element)
Selector.__index = Selector
function Selector.new(s) s = s or if type(s.class)
function Selector:check(e) if getmetatable(e) ~= Element then return false end -- all selector if self.yes then return true end -- id selector if self.id and e.id ~= self.id then return false end -- type selector if self.type and e.type ~= self.type then return false end -- class selector if #self.class > 0 then local class = true for _,v in pairs(self.class) do if not TableTools.inArray(e.classes, v) then class = false break end end if not class then return false end end -- direct parent check if self.directParent and not self.directParent:check(e.parent) then return false end -- parent check
if self.parent then local nextParent = e.parent while true do if nextParent
--------------------------------p.Element = Elementp.Selector = Selectorreturn p