Module:Sandbox

*Documentation for this module may be created at Module:Sandbox/doc*

```
local p = {}

local utils = require( "Module:Utils" )

local languages = {
 latin = "Latin",
 greek = "Greek",
 sanskrit = "Sanskrit",
 aramaic = "Aramaic",
 mandaic = "Deep Mandaic",
 phrygian = "Phrygian",
 fucine = "Fucine",
 vak = "Vak"
}

local loreColors = {
 grail = "fe6150",
 moth = "f2e9c2",
 lantern = "ffe300",
 forge = "ff8e3e",
 heart = "fe7e8b",
 edge = "d7dd49",
 winter = "beeeff",
 knock = "b54efc",
 secrethistories = "fe43f0"
}

local function renderBookInfoBox(id, book)
 return string.format(
 '<table class="infobox" width="260px" align="right" style="padding:1em;"><tr><th colspan="2">%s</th></tr><tr><td colspan="2"><div class="center"><div class="floatnone">[[File:%s.png|label|260px]]</div></div></td></tr><tr><td><b>Aspects</b></td><td>%s%s</td></tr><tr><td><b>ElementID</b></td><td>%s%s%s</td></tr></table>',
 book.label,
 id,
 renderAspects(book.aspects),
 book.unique and "<br/>Unique" or "",
 id,
 book.translatedId and ("<br/>" .. book.translatedId) or "",
 (id == "geminiadfucine") and "<br/>geminiadread" or ""
 )
end

local function renderFragment(fragment, withName)
 local aspects = mw.loadData("Module:Aspects/data")
 for aspect, value in pairs(fragment.aspects) do
 if loreColors[aspect] then
 local namePart = ""
 if withName then
 namePart =
 string.format(
 '[[%s|<span style="font-weight:bold;color:#%s;">%s</span>]] - ',
 aspects[aspect].label,
 loreColors[aspect],
 fragment.label
 )
 end
 return namePart ..
 "[[" ..
 aspects[aspect].label ..
 '|<span style="font-weight:bold;color:#' ..
 loreColors[aspect] .. ';">' .. aspects[aspect].label .. "</span>]]" .. " " .. value
 end
 end
end

function renderAspects(aspects)
 local aspectsData = mw.loadData("Module:Aspects/data")

 local t = {}

 for aspect, value in pairs(aspects) do
 if loreColors[aspect] then
 table.insert(
 t,
 "[[" ..
 aspectsData[aspect].label ..
 '|<span style="font-weight:bold;color:#' ..
 loreColors[aspect] .. ';">' .. aspectsData[aspect].label .. "</span>]]" .. " " .. value
 )
 else
 if value == 1 then
 table.insert(t, "[[" .. aspectsData[aspect].label .. "]]")
 else
 table.insert(t, "[[" .. aspectsData[aspect].label .. "]] " .. value)
 end
 end
 end

 return table.concat(t, "<br/>")
end

function getBookLocations(bookId)
 local vaults = mw.loadData("Module:Vaults/data")
 local vaultRewards = mw.loadData("Module:Vaults/rewardsData")
 local tomes = mw.loadData("Module:Books/tomesData")

 local t = {}

 if utils.listContainsItem(tomes.commontomes.items, bookId) then
 table.insert(t, "[[Morland’s Shop]]")
 end
 if utils.listContainsItem(tomes.auctionedcommontomes.items, bookId) then
 table.insert(t, "[[Oriflamme’s Auction House]]")
 end
 for \_, vault in pairs(vaults) do
 if vault.rewards[bookId] then
 table.insert(t, "[[" .. vault.label .. "]]")
 end
 if vault.randomRewards then
 for deckId in pairs(vault.randomRewards) do
 if utils.listContainsItem(vaultRewards[deckId].items, bookId) then
 table.insert(t, "[[" .. vault.label .. "]] chance")
 end
 end
 end
 end

 return t
end

function p.byName(frame)
 local books = mw.loadData("Module:Sandbox/data")
 local fragments = mw.loadData("Module:Fragments/data")
 local rites = mw.loadData("Module:Rites/data")

 frame = frame or {args = {}}
 local pageTitle = frame.args[1] or frame.args["name"] or mw.title.getCurrentTitle().text
 local extraHeader = frame.args["header"] or ""

 -- for debugging; if it's on the module page set the title to something known
 if pageTitle == "Books" then
 pageTitle = "De Horis (Book 1)"
 end

 local bookId, book = utils.findByLabel(books, pageTitle)

 local t = {}

 table.insert(t, renderBookInfoBox(bookId, book))

 table.insert(t, "'''" .. pageTitle .. "''' is a [[Books|Book]]. " .. extraHeader)

 table.insert(t, "== Text ==")
 if book.untranslatedDescription and book.untranslatedDescription ~= book.description then
 table.insert(t, utils.renderQuote(book.untranslatedDescription, "Untranslated description"))
 end
 table.insert(t, utils.renderQuote(book.description, "Description"))

 if book.startDescription then
 table.insert(t, utils.renderQuote(book.startDescription, "Study start text"))
 table.insert(t, utils.renderQuote(book.endDescription, "Study end text"))
 end

 table.insert(t, "== Rewards ==")
 for \_, reward in ipairs(book.rewards or {}) do
 if fragments[reward] then
 table.insert(t, "\* " .. renderFragment(fragments[reward], true))
 end
 if rites[reward] then
 table.insert(t, "\* [[Rites|" .. rites[reward].label .. "]]")
 end
 if not fragments[reward] and not rites[reward] then
 if utils.startsWith(reward, "scholar") then
 table.insert(t, "\* [[Scholar: " .. (languages[reward:sub(8)] or reward:sub(8)) .. "]]")
 elseif reward == "eruditionplus" then
 table.insert(t, "\* [[Erudition: a Lesson Learnt]]")
 elseif reward == "glimmeringplus" then
 table.insert(t, "\* [[Glimmering: a Lesson Learnt]]")
 elseif reward == "geminiadread" then
 table.insert(
 t,
 '\* <span style="font-weight:bold;color:#b54efc;">The Geminiad [Read]</span> - [[Knock|<span style="font-weight:bold;color:#b54efc;">Knock</span>]] 2 [[Tools|Tool]]'
 )
 else
 table.insert(t, "\* [[" .. reward:sub(1, 1):upper() .. reward:sub(2) .. "]]")
 end
 end
 end

 table.insert(t, "== Locations ==")
 for \_, location in ipairs(getBookLocations(bookId)) do
 if (location:sub(-6) == "chance") then
 table.insert(t, "\* " .. location .. " of receiving as reward for completing this vault")
 else
 table.insert(t, "\* " .. location)
 end
 end

 table.insert(t, "[[Category: Books]]")
 if book.unique then
 table.insert(t, "[[Category: Unique]]")
 end
 table.insert(t, "[[Category: Generated Pages]]")
 return table.concat(t, "\n")
end

function p.list(frame)
 local books = mw.loadData("Module:Sandbox/data")
 local fragments = mw.loadData("Module:Fragments/data")
 local rites = mw.loadData("Module:Rites/data")

 local t = {}
 table.insert(t, '{| class="wikitable sortable"')
 table.insert(t, "|+")
 table.insert(t, '!style="width: 30%"|Title')
 table.insert(t, "!Language")
 table.insert(t, "!Fragments")
 table.insert(t, "!Rite")
 table.insert(t, "!Other")
 table.insert(t, "!Location")

 local bookLabelToId = {}
 local bookLabels = {}
 for bookId, book in pairs(books) do
 bookLabelToId[book.label] = bookId
 table.insert(bookLabels, book.label)
 end
 table.sort(bookLabels)

 for \_, bookLabel in ipairs(bookLabels) do
 local bookId = bookLabelToId[bookLabel]
 local book = books[bookId]
 if book.aspects.text then
 table.insert(t, "|-")
 table.insert(t, "|[[" .. book.label .. "]]")
 table.insert(t, "|")
 for aspect in pairs(book.aspects or {}) do
 if aspect:len() > 4 and utils.startsWith(aspect, "text") then
 table.insert(t, "[[" .. (languages[aspect:sub(5)] or aspect:sub(5)) .. "]]")
 break
 end
 end
 table.insert(t, "|")
 for \_, reward in ipairs(book.rewards or {}) do
 if fragments[reward] then
 table.insert(t, renderFragment(fragments[reward], false) .. "<br/>")
 end
 end
 table.insert(t, "|")
 for \_, reward in ipairs(book.rewards or {}) do
 if rites[reward] then
 table.insert(t, "[[Rites|" .. rites[reward].label .. "]]")
 end
 end
 table.insert(t, "|")
 for \_, reward in ipairs(book.rewards or {}) do
 if not fragments[reward] and not rites[reward] then
 if utils.startsWith(reward, "scholar") then
 table.insert(t, "[[Scholar: " .. (languages[reward:sub(8)] or reward:sub(8)) .. "]]")
 elseif reward == "eruditionplus" then
 table.insert(t, "[[Erudition: a Lesson Learnt]]")
 elseif reward == "glimmeringplus" then
 table.insert(t, "[[Glimmering: a Lesson Learnt]]")
 elseif reward == "geminiadread" then
 table.insert(
 t,
 '\* <span style="font-weight:bold;color:#b54efc;">The Geminiad [Read]</span> - [[Knock|<span style="font-weight:bold;color:#b54efc;">Knock</span>]] 2 [[Tools|Tool]]'
 )
 else
 table.insert(t, "[[" .. reward:sub(1, 1):upper() .. reward:sub(2) .. "]]")
 end
 end
 end
 table.insert(t, "|")
 table.insert(t, table.concat(getBookLocations(bookId), "<br/>\n"))
 end
 end

 table.insert(t, "|}")

 return table.concat(t, "\n")
end

function p.byLanguage(frame)
 local language = "text" .. string.lower((frame or {args = {}}).args[1] or "latin")

 local books = mw.loadData("Module:Books/data")

 local bookLabels = {}
 for \_, book in pairs(books) do
 if book.aspects[language] then
 table.insert(bookLabels, book.label)
 end
 end

 table.sort(bookLabels)

 local t = {}
 for \_, label in pairs(bookLabels) do
 table.insert(t, "\* [[" .. label .. "]]")
 end
 return table.concat(t, "\n")
end

function p.byFragment(frame)
 local fragmentAspect = (frame or {args = {}}).args[1] or "winter"
 local books = mw.loadData("Module:Books/data")
 local fragments = mw.loadData("Module:Fragments/data")

 local bookLabels = {}
 local bookLabelToFragmentLevel = {}
 for \_, book in pairs(books) do
 for \_, reward in ipairs(book.rewards or {}) do
 local fragment = fragments[reward]
 if fragment and fragment.aspects[fragmentAspect] then
 table.insert(bookLabels, book.label)
 bookLabelToFragmentLevel[book.label] = fragment.aspects[fragmentAspect]
 end
 end
 end

 table.sort(bookLabels)

 local t = {}
 table.insert(t, '{| class="wikitable sortable"')
 table.insert(t, "|+")
 table.insert(t, "!Book")
 table.insert(t, "!Fragment level")
 for \_, label in pairs(bookLabels) do
 table.insert(t, "|-")
 table.insert(t, "|[[" .. label .. "]]")
 table.insert(t, "|" .. bookLabelToFragmentLevel[label])
 end
 table.insert(t, "|}")
 return table.concat(t, "\n")
end

return p

```