Module:SuperNav

local p = {} -- The navbox we will create and return local navbox = mw.html.create("div") -- Prevent from being printed by ebook maker navbox :addClass("print-no") :addClass("entry-unrelated")

--- Searching for the prefix corresponding the project -- @param #string pageName the name to search -- @param #table prefixData all prefixes stocked function searchPrefix(pageName, prefixData) -- Finding and returning the longest matching key local keyFounded = '' for key, var in pairs(prefixData) do       if mw.ustring.find(mw.ustring.lower(pageName),mw.ustring.lower(key),1,true) ~= nil then if mw.ustring.len(key) > mw.ustring.len(keyFounded) then keyFounded = key end end end return keyFounded end

--- Personalizing the Navbox according to parameters -- @param #table args all parameters transmitted function customSkin(args) -- Loading the default skin for Navbox local defaultSkin = mw.loadData("Module:Default Nav Skin") or {} local skin = {} for key, var in pairs(defaultSkin) do       skin[key] = (mw.text.trim(tostring(var))) end for key, var in pairs(args) do       skin[key] = (mw.text.trim(tostring(var))) end return skin end

--- Make wikia interne link from page name -- @param #table data containing full name, short name, etc. associating this page from pagesList -- @param #boolean shortened shorten the name of page or not -- @param #string style styling this link function wikiaLink(data, shortened, style) local appear_text = mw.html.create("span") appear_text:cssText(style) if shortened then appear_text:wikitext(data.shortname or data.fullname) else appear_text:wikitext(data.longname or data.fullname) end return "" .. tostring(appear_text) .."" end

--- Create the local navigator (forwarding/backwarding) -- @param #string pageName name of this page -- @param #table pagesList all the pages of this project -- @param #table customizedSkin personalizing parameters function makeLocalNav(pageName,pagesList,customizedSkin) --Looking for mainpage local mainPageData, mainPagePos = {}, 0 for k, v in ipairs(pagesList) do       if v.mainpage then mainPageData = v           mainPagePos = k            break end end --Determining the position of this page, couting the number of pages as well (n) local actualPos, n = 0, 0 for k, v in ipairs(pagesList) do       n = n + 1 if v.fullname == pageName then actualPos = k       end end if actualPos == 0 then actualPos = mainPagePos end --Determining the preceding page local previousPageData = {} if actualPos > 1 then if not pagesList[actualPos - 1].mainpage then previousPageData = pagesList[actualPos - 1] end end --Determining the successing page local nextPageData = {} if actualPos < n then if not pagesList[actualPos + 1].mainpage then nextPageData = pagesList[actualPos + 1] end end --Constructing html local localNav, localNav_row, previousPage, mainPage, nextPage = mw.html.create("table"), mw.html.create("tr"), mw.html.create("td"), mw.html.create("td"), mw.html.create("td")

previousPage :cssText(customizedSkin.previousPage) if previousPageData.longname ~= nil then previousPage:wikitext("► Xem lại " .. wikiaLink(previousPageData,false,customizedSkin.previousPage_link) .. " ◄") else previousPage:wikitext(" ") end

mainPage :cssText(customizedSkin.mainPage) if mainPageData.fullname ~= nil then mainPage:wikitext(customizedSkin.mainPage_left .. wikiaLink(mainPageData,true,customizedSkin.mainPage_link) .. customizedSkin.mainPage_right) else mainPage:wikitext(" ") end

nextPage :cssText(customizedSkin.nextPage) if nextPageData.longname ~= nil then nextPage:wikitext("► Xem tiếp " .. wikiaLink(nextPageData,false,customizedSkin.nextPage_link) .. " ◄") else nextPage:wikitext(" ") end

localNav_row :cssText(customizedSkin.localNav_row) :node(previousPage) :node(mainPage) :node(nextPage)

localNav :cssText(customizedSkin.localNav) :node(localNav_row)

return localNav end

--- Create the list of all pages in the project -- @param #table pagesList all the pages of this project -- @param #table customizedSkin personalizing parameters function makeGlobalNav(pagesList,customizedSkin) -- Ordering and grouping pages according to volume's numeration local groupedPages, orderedKeys = {}, {} for _, v in ipairs(pagesList) do       if v.id then local thisVol = {ft = v, ch = {}} for _, v2 in ipairs(pagesList) do               if v2.childOf == v.id then table.insert(thisVol.ch, v2) end end table.insert(orderedKeys, v.id) groupedPages[v.id] = thisVol end end

-- Constructing html local globalNav, globalNav_title, globalNav_content, unitNodes = mw.html.create("div"), mw.html.create("div"), mw.html.create("div"), {}

-- title globalNav_title :cssText(customizedSkin.globalNav_title) :addClass("mw-customtoggle-globalNav"):addClass("mw-customtoggle-globalNavClose"):addClass("mw-customtoggle-globalNavOpen") :wikitext(customizedSkin.globalNav_title_text)

-- content -- constructing unit nodes, which consist of volumes for _, id in ipairs(orderedKeys) do       -- for each volume local data, vol, links = groupedPages[id], mw.html.create("table"), mw.html.create("") -- fulltext link local ft = mw.html.create("td") ft           :cssText(customizedSkin.fulltext) :wikitext(wikiaLink(data.ft,true,customizedSkin.fulltext_link)) links:node(ft) -- chapter link for _, chapter in ipairs(data.ch) do           local ch = mw.html.create("td") ch               :cssText(customizedSkin.chapter) :wikitext(wikiaLink(chapter,true,customizedSkin.chapter_link)) links:node(ch) end -- volume case vol :cssText(customizedSkin.volume) :node(mw.html.create("tr"):node(links)) -- attaching to unitNodes -- unitNodes and groupedPages used the same table of ordered keys unitNodes[id] = vol end -- constructing arcs local arcsStructure = pagesList.arcsStructure if arcsStructure then for _, arc in ipairs(arcsStructure) do           if arc.including and arc.id then local arc_node, title, content = mw.html.create(""), mw.html.create("div"), mw.html.create("div") -- styling title :addClass("mw-customtoggle-"..arc.id):addClass("mw-customtoggle-"..arc.id.."Close"):addClass("mw-customtoggle-"..arc.id.."Open") :wikitext(arc.fullname) if not customizedSkin["arcBar_title_"..arc.id] then title:cssText(customizedSkin.arcBar_title) else title:cssText(customizedSkin["arcBar_title_"..arc.id]) end

content :addClass("mw-collapsible"):addClass("mw-collapsed") :attr("id", "mw-customcollapsible-"..arc.id) if not customizedSkin["arcBar_content_"..arc.id] then content:cssText(customizedSkin.arcBar_content) else content:cssText(customizedSkin["arcBar_content_"..arc.id]) end

-- grouping all unit nodes into @arc_node for _, includedId in ipairs(arc.including) do                   content:node(unitNodes[includedId]) end arc_node:node(title):node(content) -- deleting included nodes and inserting arc_node into unitNodes for index, includedId in ipairs(arc.including) do                   unitNodes[includedId] = nil end unitNodes[arc.id] = arc_node -- deleting corresponding keys and inserting arc.id into orderedKeys at the first deleted key local index = 1 repeat -- comparing orderedKeys[index] with all includedId in arc.including for i, includedId in ipairs(arc.including) do                       if includedId == orderedKeys[index] then if i==1 then orderedKeys[index] = arc.id                           else table.remove(orderedKeys, index) index = index - 1 end end end index = index + 1 until orderedKeys[index] == nil end end end

-- appending volume cases, arc cases to globalNav_content for _, key in ipairs(orderedKeys) do       globalNav_content:node(unitNodes[key]) end

globalNav_content :cssText(customizedSkin.globalNav_content) :attr("id", "mw-customcollapsible-globalNav") :addClass("mw-collapsible") if (customizedSkin.collapse_globalNav == "true") then globalNav_content :addClass("mw-collapsed") :cssText("display:none") end

-- overall globalNav :cssText(customizedSkin.globalNav) :addClass("hidden") :node(globalNav_title) :node(globalNav_content)

return globalNav end

--- Searching function --- Returns the first link, in shortened form, matching the given keyword. If research fails, it returns the mainpage -- @param #keyword -- @param #pagesList function search(keyword, pagesList) --Looking for mainpage local mainPageData = {} for _, v in ipairs(pagesList) do       if v.mainpage then mainPageData = v           break end end --Determining the corresponding link of keyword local dataFound = nil for _, v in ipairs(pagesList) do       if mw.ustring.find(mw.ustring.lower(v.fullname),mw.ustring.lower(keyword),1,true) ~= nil then dataFound = v			break end end if dataFound == nil then return wikiaLink(mainPageData, true, nil) else return wikiaLink(dataFound, true, nil) end end

--- The main function -- @param #table frame what wikia transmits function p.makeNav( frame ) -- Getting all parameters transmis via template Auto Nav, including and customized Navbox's styles local args = frame.args or {} -- Getting the title of page using template Auto Nav local pageName = args["pageName"] -- The prefixes local prefixData, pagesList = mw.loadData("Module:PrefixData") -- Getting the list of pages belonging to this project if args.src then pagesList = mw.loadData(args.src) else local prefixUsed = searchPrefix(pageName, prefixData) pagesList = mw.loadData(prefixData[prefixUsed]) end if args.search == "" or args.search == nil then -- if user does not give value to arguement "search", then we create a navbox by default local customizedSkin = customSkin(args) local inner_navbox = mw.html.create("div") inner_navbox :addClass("dotEPUBremove") -- Append the local nav into our inner_navbox inner_navbox:node(makeLocalNav(pageName,pagesList,customizedSkin)) -- Append the global nav into our inner_navbox inner_navbox:node(makeGlobalNav(pagesList,customizedSkin)) -- Append the inner into navbox navbox:node(inner_navbox) return navbox else return search(args.search, pagesList) end end

return p