Module:Shindo

--- This is the Shindo module. Named after the Japanese term used for classifying earthquakes {{lang|ja|{{ruby|[[wikt:震度|震度]]|しんど}}}}, this module provides utility for seismic intensity scales.-- -- Seismic intensity data generated on [[Module:Shindo/data]]. Messages on [[Module:Shindo/messages]].-- @module shindo-- @alias p-- @require Module:Arguments-- @require Module:MakeInvokeFunc-- @require Module:Message-- @require Module:Yesno-- @release beta-- local p = {}local getArgs = require("Module:Arguments").getArgslocal data = mw.loadData("Module:Shindo/data")local messages = mw.loadData("Module:Shindo/messages")local makeInvokeFunc = require("Module:MakeInvokeFunc")(p)local message = require("Module:Message")(messages)local yn = require("Module:Yesno")--- Gets the grayscale value of a specific color-- @function getValueOfColor-- @param {table} tbl table for colors-- @param {number} tbl[1] red value-- @param {number} tbl[2] green value-- @param {number} tbl[3] blue value-- @return {number} Decimal value of the color.local function getValueOfColor(tbl)return (tbl[1] + tbl[2] + tbl[3]) / 3 / 255end--- Gets the color as a comma-separated value for CSS-- @function rgbColor-- @param {table} tbl table for colors-- @param {number} tbl[1] red value-- @param {number} tbl[2] green value-- @param {number} tbl[3] blue value-- @return {string} The color in the format red, green, bluelocal function rgbColor(tbl)return tbl[1] .. (tbl[2] and ", " .. tbl[2] .. (tbl[3] and ", " .. tbl[3] or "") or "")end--- Gets the average of multiple colors-- @function averageColor-- @param {table} tbl table of multiple colors-- @return {number} Decimal value of the color.local function averageColor(tbl)local colors = {}for k,v in pairs(tbl) docolors[k] = vendlocal avg = {0, 0, 0}for _,color in pairs(colors) doavg[1] = avg[1] + color[1]avg[2] = avg[2] + color[2]avg[3] = avg[3] + color[3]endavg[1] = math.ceil(avg[1] / #colors) - avg[1] / #colors > 0.5 and math.floor(avg[1] / #colors) or math.ceil(avg[1] / #colors)avg[2] = math.ceil(avg[2] / #colors) - avg[2] / #colors > 0.5 and math.floor(avg[2] / #colors) or math.ceil(avg[2] / #colors)avg[3] = math.ceil(avg[3] / #colors) - avg[3] / #colors > 0.5 and math.floor(avg[3] / #colors) or math.ceil(avg[3] / #colors)return avgend--- Gets all the intensity values from a scale-- @function listIntensitiesFromScale-- @param {string} scale First scale name-- @param {string} intensities Table of intensity values-- @param {boolean} labelScale Whether to label a scale-- @param {string} scale Second scale name-- @return {string} List of intensitieslocal function listIntensitiesFromScale(scale, intensities, labelScale, scale2)local out = ''if yn(labelScale) thenout = out .. data[scale].short .. ' 'endlocal categoriesAreSame = truelocal category = ""for k,v in pairs(intensities) doif data[scale].ranks[v] == nil then error(message("invalidIntensity", {v, scale})) endout = out .. data[scale].ranks[v].labelif k ~= #intensities thenif #intensities == 2 thenout = out .. '–'elseout = out .. '/'endendif category == "" and categoriesAreSame thencategory = data[scale].ranks[v].category or ""endcategoriesAreSame = categoriesAreSame and category ~= "" and (data[scale].ranks[v].category and data[scale].ranks[v].category == category or false)endif categoriesAreSame and category ~= "" and not scale2 thenout = out .. " (''" .. category .. "'')"endreturn outend--- Gets the inline CSS for a particular scale's intensity color-- @function p._color-- @param {table} args frame arguments-- @param {string} args.scale The name of the scale-- @param {string} args.intensity The intensity of the scale-- @return {string} Preprocessed text outputp._color = function(args)local scale = string.lower(args.scale or args[1] or error(message("noScaleShortCode")))local intensity = string.upper(args.intensity or args[2] or error(message("noIntensity")))if data[scale] == nil then error(message("invalidScale", {scale})) endif data[scale].ranks[intensity] == nil then error(message("invalidIntensity", {intensity, scale})) endlocal order = data[scale].ranks[intensity].orderlocal color = data[scale].colors[order]local colorIntensity = getValueOfColor(color)return 'background-color:rgb(' .. rgbColor(color) .. '); color:' .. (colorIntensity < 0.5 and "white" or "black") .. ";"end--- Gets the format of the scale as a wikitable-- @function p._formatInWikitable-- @param {table} args frame arguments-- @param {string} args.scale The name of the scale-- @param {string} args.intensity The intensity of the scale-- @param {string} args.tagProps additional properties for the wikitable row-- @param {boolean} args.header if the formatting is done as a header-- @param {boolean} args.link whether to link to the scale page-- @param {boolean} args.labelScale whether to include the name of the scale-- @return {string} Preprocessed text outputp._formatInWikitable = function(args)local scale = string.lower(args.scale or args[1] or error(message("noScaleShortCode")))local link = args.link ~= nil and args.link or truelocal labelScale = args.labelScale ~= nil and args.labelScale or truelocal doColor = args.color ~= nil and args.color or truelocal intensity = string.upper(args.intensity or args[2] or error(message("noIntensity")))local intensities = mw.text.split(intensity, "/") or { intensity }if data[scale] == nil then error(message("invalidScale", {scale})) endlocal colors = {}for k,v in pairs(intensities) dolocal order = data[scale].ranks[v].ordercolors[k] = data[scale].colors[order]endlocal color = averageColor(colors)local colorIntensity = getValueOfColor(color)local out = ""if yn(args.header or false) thenout = out .. "! " elseout = out .. "| "endout = out .. (args.tagProps ~= nil and args.tagProps or "")if (yn(doColor)) thenout = out .. 'style="background-color:rgba(' .. rgbColor(color) .. '); color:' .. (colorIntensity < 0.5 and "white" or "black") .. ';' .. (args.style or "") .. '" | 'elseif (args.style) thenout = out .. 'style="' .. (args.style or "") .. '" | 'endif yn(link) thenout = out .. '[[' .. data[scale].name .. "#" .. data[scale].id_prefix .. data[scale].ranks[intensity].id .. "|"endif yn(doColor) thenout = out .. '<span style=\"color:' .. (colorIntensity < 0.5 and "white" or "black") .. ';">'endout = out .. listIntensitiesFromScale(scale, intensities, labelScale, false)if yn(doColor) thenout = out .. '</span>'endif yn(link) thenout = out .. "]]"endreturn outend--- Gets the format of the scale as a tag-- @function p._formatTag-- @param {table} args frame arguments-- @param {string} args.scale The name of the scale-- @param {string} args.scale2 The name of a second scale-- @param {string} args.intensity The intensity of the scale-- @param {string} args.intensity2 The intensity for the second scale-- @param {string} args.tag Tag name-- @param {string} args.style styling for the tag-- @param {string} args.tagProps additional properties for the tag-- @param {boolean} args.color Whether to color the entry-- @param {boolean} args.link whether to link to the scale page-- @return {string} Preprocessed text outputp._formatTag = function(args)local scale = string.lower(args.scale or args[1] or error(message("noScaleShortCode")))local scale2 = args.scale2 or args[3] or nilif scale2 ~= nil then scale2 = string.lower(scale2) endlocal link = args.link ~= nil and args.link or truelocal labelScale = args.labelScale ~= nil and args.labelScale or truelocal doColor = args.color ~= nil and args.color or truelocal intensity = string.upper(args.intensity or args[2] or error(message("noIntensity")))local intensities = mw.text.split(intensity, "/") or { intensity }local intensity2 = args.intensity2 or args[4] or (scale2 and error(message("noIntensity"))) or nillocal intensities2 = {}if intensity2 ~= nil thenintensity2 = string.upper(intensity2)intensities2 = mw.text.split(intensity2, "/") or { intensity2 }endif data[scale] == nil then error(message("invalidScale", {scale})) endif scale2 and data[scale2] == nil then error(message("invalidScale", {scale2})) endlocal colors = {}for k,v in pairs(intensities) dolocal order = data[scale].ranks[v].ordercolors[k] = data[scale].colors[order]endlocal color = averageColor(colors)local colorIntensity = getValueOfColor(color)local out = ''if yn(doColor) thenout = out .. '<' .. (args.tag or "span") .. ' style="background-color:rgba(' .. rgbColor(color) .. '); padding:4px; color:' .. (colorIntensity < 0.5 and "white" or "black") .. '; 'elseif args.style thenout = out .. '<' .. (args.tag or "span") .. ' style="'elseout = out .. '<' .. (args.tag or "span")endif args.style thenout = out .. args.styleout = out .. '" 'elseif yn(doColor) thenout = out .. '" 'endout = out .. (args.tagProps ~= nil and args.tagProps or "")out = out .. ">"if yn(link) thenout = out .. '[[' .. data[scale].name .. "#" .. data[scale].id_prefix .. data[scale].ranks[intensities[1]].id .. "|"endif yn(doColor) thenout = out .. '<span style=\"color:' .. (colorIntensity < 0.5 and "white" or "black") .. ';">'endout = out .. listIntensitiesFromScale(scale, intensities, labelScale, scale2)if yn(doColor) thenout = out .. '</span>'endif yn(link) thenout = out .. "]]"endif (scale2) thenout = out .. " ("if yn(link) thenout = out .. '[[' .. data[scale2].name .. "#" .. data[scale2].id_prefix .. data[scale2].ranks[intensities2[1]].id .. "|"endif yn(doColor) thenout = out .. '<span style=\"color:' .. (colorIntensity < 0.5 and "white" or "black") .. ';">'endout = out .. listIntensitiesFromScale(scale2, intensities2, true, true)if yn(doColor) thenout = out .. '</span>'endif yn(link) thenout = out .. "]]"endout = out .. ")"endout = out .. '</' .. (args.tag or "span") .. '>'return mw.getCurrentFrame():preprocess(out)endp._format = function(args)if args["format"] == "wikitable" thenreturn p.formatInWikitable(args)elsereturn p.formatTag(args)endendp._getScaleName = function(args)local scale = string.lower(args.scale or args[1] or error(message("noScaleShortCode")))if data[scale] == nil then error(message("invalidScale", {scale})) endlocal out = ''if yn(args.link or true) thenout = out .. '[[' .. data[scale].name .. '|'endout = out .. data[scale].nameif yn(args.link or true) thenout = out .. ']]'endreturn outend-- uses binary search to convert a peak ground acceleration to a seismic intensityfunction convert(pga, ranks, ranksSorted, left, right)left = left ~= nil and left or 0right = right ~= nil and right or #ranksSortedindex = math.floor((left + right) / 2)local lower = ranks[ranksSorted[index + 1]].pgalocal upper = ranksSorted[index + 2] and ranks[ranksSorted[index + 2]].pga or math.hugeif (pga >= upper) thenreturn convert(pga, ranks, ranksSorted, index, right)elseif (pga < lower) thenreturn convert(pga, ranks, ranksSorted, left, index)elsereturn ranksSorted[index + 1]endendp._convert = function(args)local scale = string.lower(args.scale or args[1] or error(message("noScaleShortCode")))if data[scale] == nil then error(message("invalidScale", {scale})) endlocal ranksSorted = {}for k,v in ipairs(data["mmi"].ranksSorted) do ranksSorted[k] = v endreturn convert(tonumber(args.pga or args[2]), data[scale].ranks, ranksSorted)endp.convert1 = convert --debuggingp._list = function(args)local out = mw.html.create('ul')for k,v in pairs(data) dolocal list = out:tag('li')list:wikitext('<code>' .. k .. '</code>: [[' .. v.name .. '|' .. v.name .. ']]')local tb = list:tag('table'):addClass("wikitable")tb:tag("tr"):tag("th"):wikitext("Seismic intensity"):done():tag("th"):wikitext("Display"):done():done()for l,w in pairs(v.order) dotb:tag('tr'):wikitext('<td><code>' .. w .. '</code></td> ' .. p.format({k, w, tag = "td"})):done()endlist:done()endout:allDone()return tostring(out)end-- make each scale invokablefor k,v in pairs(data) doif p["_" .. k] ~= nil then error(message("scaleNameInvalid", k)) endp["_" .. k] = function(args)args["scale"] = kargs["intensity"] = args["intensity"] or args[1] or nilargs["scale2"] = args["scale2"] or args[2] or nilargs["intensity2"] = args["intensity2"] or args[3] or nilif args["format"] == "wikitable" thenreturn p.formatInWikitable(args)elsereturn p.formatTag(args)endendend-- make all functions that begin with _ invokablelocal q = mw.clone(p)for k,v in pairs(q) doif mw.ustring.sub(k, 1, 1) == "_" thenp[mw.ustring.sub(k, 2, #k)] = makeInvokeFunc(k)endendreturn p
Retrieved from "https://en.wikipedia.org/w/index.php?title=Module:Shindo&oldid=1262320074"