Module:Scenes

local p = {} -- retrieves the database local data = mw.loadData("Module:Scenes/data") local scenes = data.scenes local extras = data.extras

-- from stackoverflow/2705793 function tablelength(T) local count = 0 for _ in pairs(T) do count = count + 1 end return count end

-- takes a table of strings and returns a HTML ul function table2ul(t) if tablelength(t) == 0 then return '' end local s = {} table.insert(s, '') for _,v in pairs(t) do       table.insert(s, '' .. v .. '') end table.insert(s, '') return table.concat(s) end

-- converts number of frames to number of seconds function p.timecodeToTime(T, rate) local secs = math.floor(T / rate + 0.5) return secs end

-- converts number of seconds to h:mm:ss or m:ss function p.timeToReadable(T, withHours) local secs = T%60 local mins local hours local result if withHours then mins = math.floor(T/60)%60 hours = math.floor(T/3600) result = hours .. ":" .. string.rep(0,2-string.len(mins)) .. mins .. ":" .. string.rep(0,2-string.len(secs)) .. secs else mins = math.floor(T/60) result = mins .. ":" .. string.rep(0,2-string.len(secs)) .. secs end return result end

-- converts an appearance code to text function p.appearanceText(a) local result = "" if    a:sub(1, 1) == "D" then result = "dialogue" elseif a:sub(1, 1) == "d" then result = "indirect dialogue" elseif a:sub(1, 1) == "P" then result = "physical" elseif a:sub(1, 1) == "p" then result = "indirect physical" elseif a:sub(1, 1) == "M" then result = "mention" elseif a:sub(1, 1) == "m" then result = "indirect mention" elseif a:sub(1, 1) == "*" then result = "mind" end if a:sub(2, 2) == "*" then result = result .. ", mind" end return result end

-- returns the list of scenes, for use in the scenes navbox function p.list local str local items = {} local l = tablelength(scenes) for n = 1, l-1 do       str = scenes[n].name if scenes[n].numb then items[n] = '' .. str .. '\n' else items[n] = '' end end return '' .. table.concat(items) .. '' end

-- returns the list of extras, for use in the extras navbox function p.listExtras local str local items = {} local l = tablelength(extras) for n = 1, l do       local items2 = {} str = scenes[n].heading l2 = tablelength(extras[n].content) for n2 = 1, l2 do           items2[n2] =  .. extras[n].content[n2].name ..  if extras[n].italicize == true then items2[n2] =  .. items2[n2] ..             end if n2 ~= 1 then items2[n2] = ' • ' .. items2[n2] end end items[n] = ' ' .. extras[n].heading .. ' ' .. table.concat(items2) .. ' '    end return table.concat(items) end

-- returns an item in the list of scenes, as well as derived values -- args[1] = id or index of the item -- args[2] = property to return. defaults to "name" function p.item(frame) local id = frame.args[1] or 1 id = tonumber(id) or id -- tries to convert index input local rettype = frame.args[2] or "name" local prevV = {id = "BEGINNING", name = "Beginning"} local saved = false local savedTime = 0 for k,v in pairs(scenes) do       if saved then if rettype == "next" then return v.name elseif rettype == "duration" then savedTime = p.timecodeToTime(v.timecode, 30000/1001) - savedTime return p.timeToReadable(savedTime) end end if k == id or v.id == id then if rettype == "descFormatted" then return table2ul(v.desc) elseif rettype == "appearancesFormatted" then local result = "" if v.appearances.joy ~= "" then result = result .. "Joy (" .. p.appearanceText(v.appearances.joy) .. ")\n" end if v.appearances.sadness ~= "" then result = result .. "Sadness (" .. p.appearanceText(v.appearances.sadness) .. ")\n" end if v.appearances.bb ~= "" then result = result .. "Bing Bong (" .. p.appearanceText(v.appearances.bb) .. ")\n" end if v.appearances.fear ~= "" then result = result .. "Fear (" .. p.appearanceText(v.appearances.fear) .. ")</li>\n" end if v.appearances.anger ~= "" then result = result .. "Anger (" .. p.appearanceText(v.appearances.anger) .. ")</li>\n" end if v.appearances.disgust ~= "" then result = result .. "Disgust (" .. p.appearanceText(v.appearances.disgust) .. ")</li>\n" end if v.appearances.riley ~= "" then result = result .. "Riley Andersen (" .. p.appearanceText(v.appearances.riley) .. ")</li>\n" end if v.appearances.mom ~= "" then result = result .. "Jill Andersen (" .. p.appearanceText(v.appearances.mom) .. ")</li>\n" end if v.appearances.dad ~= "" then result = result .. "Bill Andersen (" .. p.appearanceText(v.appearances.dad) .. ")</li>\n" end othersLength = tablelength(v.appearances.others) for othersItem = 1, othersLength do                   result = result .. "" .. v.appearances.others[othersItem][1] .. " (" .. p.appearanceText(v.appearances.others[othersItem][2]) .. ")</li>\n" end if result ~= "" then result = "\n" .. result .. "</ul>" end return result elseif rettype == "offset" then return p.timeToReadable(p.timecodeToTime(v.timecode, 30000/1001), 1) elseif rettype == "duration" then saved = true savedTime = p.timecodeToTime(v.timecode, 30000/1001) elseif rettype == "prev" then return prevV.name elseif rettype == "next" then saved = true elseif rettype == "diffFormatted" then local result = "" diffLength = tablelength(v.diff) for diffItem = 1, diffLength do                   result = result .. " " .. v.diff[diffItem].lang .. ": " .. v.diff[diffItem].text .. "</li>\n" end if result ~= "" then result = "\n" .. result .. "</ul>" end return result else return v[rettype] end end prevV = v   end end

-- returns an item in the list of extras, as well as derived values -- args[1] = id of the item -- args[2] = property to return. defaults to "name" function p.itemExtras(frame) local id = frame.args[1] or 1 id = tonumber(id) or id -- tries to convert index input local rettype = frame.args[2] or "name" for kCont,vCont in pairs(extras) do       for k,v in pairs(vCont.content) do            if k == id or v.id == id then if rettype == "nameFormatted" then if vCont.italicize == true then return  .. v.name ..                    else return v.name end elseif rettype == "descFormatted" then return table2ul(v.desc) elseif rettype == "appearancesFormatted" then local result = "" if v.appearances.joy ~= "" then result = result .. "Joy (" .. p.appearanceText(v.appearances.joy) .. ")</li>\n" end if v.appearances.sadness ~= "" then result = result .. "Sadness (" .. p.appearanceText(v.appearances.sadness) .. ")</li>\n" end if v.appearances.bb ~= "" then result = result .. "Bing Bong (" .. p.appearanceText(v.appearances.bb) .. ")</li>\n" end if v.appearances.fear ~= "" then result = result .. "Fear (" .. p.appearanceText(v.appearances.fear) .. ")</li>\n" end if v.appearances.anger ~= "" then result = result .. "Anger (" .. p.appearanceText(v.appearances.anger) .. ")</li>\n" end if v.appearances.disgust ~= "" then result = result .. "Disgust (" .. p.appearanceText(v.appearances.disgust) .. ")</li>\n" end if v.appearances.riley ~= "" then result = result .. "Riley Andersen (" .. p.appearanceText(v.appearances.riley) .. ")</li>\n" end if v.appearances.mom ~= "" then result = result .. "<li>Jill Andersen (" .. p.appearanceText(v.appearances.mom) .. ")</li>\n" end if v.appearances.dad ~= "" then result = result .. "<li>Bill Andersen (" .. p.appearanceText(v.appearances.dad) .. ")</li>\n" end othersLength = tablelength(v.appearances.others) for othersItem = 1, othersLength do                       result = result .. "<li>" .. v.appearances.others[othersItem][1] .. " (" .. p.appearanceText(v.appearances.others[othersItem][2]) .. ")</li>\n" end if result ~= "" then result = "<ul>\n" .. result .. "</ul>" end return result elseif rettype == "extraType" then return vCont.singular else return v[rettype] end end end end end

-- lists appearances of a major character function p.charAppearances(frame) local c = frame.args[1] or "joy" local mindOnly = frame.args[2] or "0" local str local app local items = {} local l = tablelength(scenes) if mindOnly == "1" then for n = 1, l-1 do           str = scenes[n].name if scenes[n].appearances[c]:sub(-1) == "*" then items[n] = '<li>' .. str .. '</li>\n' else items[n] = '' end end else for n = 1, l-1 do           str = scenes[n].name if scenes[n].appearances[c] ~= "" then app = p.appearanceText(scenes[n].appearances[c]) items[n] = '<li>' .. str .. ' (' .. app .. ')</li>\n' else items[n] = '' end end end local items2 = {} local ll = tablelength(extras) for nn = 1, ll do       local items2in = {} local l = tablelength(extras[nn].content) if mindOnly == "1" then for n = 1, l do               str = extras[nn].content[n].name if extras[nn].content[n].appearances[c]:sub(-1) == "*" then app = p.appearanceText(extras[nn].content[n].appearances[c]) if extras[nn].italicize == true then items2in[n] = '<li>\'\'[' .. '[' .. str .. ']]\'\'</li>\n' else items2in[n] = '<li>[' .. '[' .. str .. ']]</li>\n' end else items2in[n] = '' end end else for n = 1, l do               str = extras[nn].content[n].name if extras[nn].content[n].appearances[c] ~= "" then app = p.appearanceText(extras[nn].content[n].appearances[c]) if extras[nn].italicize == true then items2in[n] = '<li>\'\'[' .. '[' .. str .. ']]\'\' (' .. app .. ')</li>\n' else items2in[n] = '<li>[' .. '[' .. str .. ']] (' .. app .. ')</li>\n' end else items2in[n] = '' end end end items2[nn] = table.concat(items2in) if items2[nn] ~= "" then items2[nn] = '<li>' .. extras[nn].heading .. ':<ul>\n' .. items2[nn] .. '</ul>' end end return '<ul><li>\'\'Inside Out\'\':<ul>\n' .. table.concat(items) .. '</ul></li>' .. table.concat(items2) .. '</ul>' end

-- FOR "Inside Out scenes" -- generates scene list function p.fullList local number = 0 local numberText local str local desc local fullDesc local items = {} local descItems local l = tablelength(scenes) for n = 1, l-1 do       if scenes[n].list then if scenes[n].numb then number = number + 1 numberText = number else numberText = '-' end str = scenes[n].name desc = tablelength(scenes[n].desc) if desc == 0 then fullDesc = '' else descItems = {} for d = 1, desc do                   descItems[d] = '<li>' .. scenes[n].desc[d] .. '</li>' end fullDesc = '<ul>' .. table.concat(descItems) .. '</ul>' end items[n] = ' ' .. numberText .. ' ' .. str .. ' ' .. fullDesc .. ' \n' else items[n] = '' end end return ' ' end

-- generates scene length table function p.sceneLengths local str local beginTime local endTime local length local items = {} local l = tablelength(scenes) for n = 1, l-1 do		str = scenes[n].name beginTime = p.timecodeToTime(scenes[n].timecode, 30000/1001) endTime = p.timecodeToTime(scenes[n+1].timecode, 30000/1001) length = endTime-beginTime items[n] = ' ' .. str .. ' ' .. p.timeToReadable(beginTime, 1) .. ' ' .. p.timeToReadable(endTime, 1) .. ' ' .. p.timeToReadable(length) .. ' \n' end return ' ' end

-- generates appearance table function p.appearances local str local appear local items = {} local l = tablelength(scenes) for n = 1, l-1 do		if scenes[n].numb then str = scenes[n].name appear = scenes[n].appearances items[n] = ' ' .. str .. ' '			items[n] = items[n] .. ' ' .. appear.joy .. ' '			items[n] = items[n] .. ' ' .. appear.sadness .. ' '			items[n] = items[n] .. ' ' .. appear.bb .. ' '			items[n] = items[n] .. ' ' .. appear.fear .. ' '			items[n] = items[n] .. ' ' .. appear.anger .. ' '			items[n] = items[n] .. ' ' .. appear.disgust .. ' '			items[n] = items[n] .. ' ' .. appear.riley .. ' '			items[n] = items[n] .. ' ' .. appear.mom .. ' '			items[n] = items[n] .. ' ' .. appear.dad .. ' '			items[n] = items[n] .. ' \n' else items[n] = '' end end local fullExtras = {} local ll = tablelength(extras) for nn = 1, ll do   	local extrasSection = {} l = tablelength(extras[nn].content) for n = 1, l do   		str = extras[nn].content[n].name appear = extras[nn].content[n].appearances if extras[nn].italicize == true then extrasSection[n] = ' \'\'[' .. '[' .. str .. ']]\'\' '   		else extrasSection[n] = ' [' .. '[' .. str .. ']] '   		end extrasSection[n] = extrasSection[n] .. ' ' .. appear.joy .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.sadness .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.bb .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.fear .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.anger .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.disgust .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.riley .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.mom .. ' '   		extrasSection[n] = extrasSection[n] .. ' ' .. appear.dad .. ' '   		extrasSection[n] = extrasSection[n] .. ' \n' end fullExtras[nn] = ' <td colspan="10" style="text-align: center;">\'\'\'' .. extras[nn].heading .. '\'\'\' \n' .. table.concat(extrasSection) end return ' ' end

-- generates download link table function p.downloadLinks local str local dl	local fullDl local items = {} local dlItems local l = tablelength(scenes) for n = 1, l-1 do		if scenes[n].noDl then items[n] = '' else str = scenes[n].name dl = tablelength(scenes[n].dl) if dl == 0 then fullDl = '' else dlItems = {} for d = 1, dl do                   dlItems[d] = '<li>' .. scenes[n].dl[d] .. '</li>' end fullDl = '<ul>' .. table.concat(dlItems) .. '</ul>' end items[n] = ' ' .. str .. ' ' .. fullDl .. ' \n' end end return ' ' end

return p