Module:Module sandbox
Appearance
![]() | Welcome to Module:Module sandbox, a Wikipedia module sandbox. This page is itself a module, and it allows you to carry out experiments related to module editing. If you wish to experiment with article editing, use the Wikipedia Sandbox or your own user sandbox.
To edit, click the edit tab above, make your changes and click the Publish changes button when finished. Click here to reset the sandbox. Please do not place malicious Lua code here, or copyrighted, offensive, illegal or libelous content in the sandboxes. For assistance with Lua coding, try the technical forum at the Village Pump. There are also several template sandboxes you can use to carry out experiments:
You can also conduct tests using the Wikipedia Sandbox. For instance, to invoke this module there, edit it so that it includes: {{#invoke:Module sandbox}} |
More info
Sandbox games |
Usage
{{#invoke:Module sandbox|function_name}}
local p = {}
local function dateCalculation(dateStr)
local year , month, day = dateStr:match("(%d+)[/.,-](%d+)[/.,-](%d+)")
if not year then
day , month, year = dateStr:match("(%d+)[/.,-](%d+)[/.,-](%d+)")
end
if not year then
return 'Invalid date format'
end
local currentDate = os.date("*t")
local age
if tonumber(year) < 1582 or (tonumber(year) == 1582 and (tonumber(month) < 10 or (tonumber(month) == 10 and tonumber(day) < 4))) then
age = currentDate.year - tonumber(year)
else
age = currentDate.year - tonumber(year)
local leapYears = 0
for i = tonumber(year), currentDate.year - 1 do
if i % 4 == 0 then
leapYears = leapYears + 1
end
end
age = age - leapYears
end
if currentDate.month < tonumber(month) or (currentDate.month == tonumber(month) and currentDate.day < tonumber(day)) then
age = age - 1
end
local monthName = os.date("%B", os.time{year=tonumber(year), month=tonumber(month), day=tonumber(day)})
return " ".. monthName .. " "..day..", " .. year.. " <br/>(Age " .. age.. ")"
end
--[[
local function dateCalculation(dateStr)
local year , month, day = dateStr:match("(%d+)[/.,-](%d+)[/.,-](%d+)")
if not year then
day , month, year = dateStr:match("(%d+)[/.,-](%d+)[/.,-](%d+)")
end
if not year then
return 'Invalid date format'
end
local currentDate = os.date("*t")
local age = currentDate.year - tonumber(year)
if currentDate.month < tonumber(month) or (currentDate.month == tonumber(month) and currentDate.day < tonumber(day)) then
age = age - 1
end
local monthName = os.date("%B", os.time{year=tonumber(year), month=tonumber(month), day=tonumber(day)})
return " ".. monthName .. " "..day..", " .. year.. " <br/>(Age " .. age.. ")"
end
]]
--❗
--[[Volume conversions]]
local function litersToGallons(liters)
local litersValue = tonumber(liters:match("%d+%.?%d*"))
if litersValue then
local gallons = litersValue * 0.264172
return "".. string.format("%.2f liters (%.2f gallons)", litersValue, gallons)
end
return liters
end
local function gallonsToLiters(gallons)
local gallonsValue = tonumber(gallons:match("%d+%.?%d*"))
if gallonsValue then
local liters = gallonsValue * 3.78541
return string.format("%.2f gallons (%.2f liters)", gallonsValue, liters)
end
return gallons
end
local function cubicMetersToCubicFeet(cubicMeters)
local cubicMetersValue = tonumber(cubicMeters:match("%d+%.?%d*"))
if cubicMetersValue then
local cubicFeet = cubicMetersValue * 35.3147
return string.format("%.2f cubic meters (%.2f cubic feet)", cubicMetersValue, cubicFeet)
end
return cubicMeters
end
local function cubicFeetToCubicMeters(cubicFeet)
local cubicFeetValue = tonumber(cubicFeet:match("%d+%.?%d*"))
if cubicFeetValue then
local cubicMeters = cubicFeetValue * 0.0283168
return string.format("%.2f cubic feet (%.2f cubic meters)", cubicFeetValue, cubicMeters)
end
return cubicFeet
end
-- Area conversions
local function squareMetersToSquareFeet(squareMeters)
local squareMetersValue = tonumber(squareMeters:match("%d+%.?%d*"))
if squareMetersValue then
local squareFeet = squareMetersValue * 10.7639
return string.format("%.2f square meters (%.2f square feet)", squareMetersValue, squareFeet)
end
return squareMeters
end
local function squareFeetToSquareMeters(squareFeet)
local squareFeetValue = tonumber(squareFeet:match("%d+%.?%d*"))
if squareFeetValue then
local squareMeters = squareFeetValue * 0.092903
return string.format("%.2f square feet (%.2f square meters)", squareFeetValue, squareMeters)
end
return squareFeet
end
local function hectaresToAcres(hectares)
local hectaresValue = tonumber(hectares:match("%d+%.?%d*"))
if hectaresValue then
local acres = hectaresValue * 2.47105
return string.format("%.2f hectares (%.2f acres)", hectaresValue, acres)
end
return hectares
end
local function acresToHectares(acres)
local acresValue = tonumber(acres:match("%d+%.?%d*"))
if acresValue then
local hectares = acresValue * 0.404686
return string.format("%.2f acres (%.2f hectares)", acresValue, hectares)
end
return acres
end
-- Time conversions
local function hoursToMinutes(hours)
local hoursValue = tonumber(hours:match("%d+%.?%d*"))
if hoursValue then
local minutes = hoursValue * 60
return string.format("%.2f hours (%d minutes)", hoursValue, minutes)
end
return hours
end
local function minutesToHours(minutes)
local minutesValue = tonumber(minutes:match("%d+%.?%d*"))
if minutesValue then
local hours = minutesValue / 60
local decimalPart = minutes:match("%.(%d+)")
if decimalPart then
hours = hours + tonumber("0." .. decimalPart)
end
return string.format("%.2f minutes (%.2f hours)", minutesValue, hours)
end
return minutes
end
local function daysToHours(days)
local daysValue = tonumber(days:match("%d+%.?%d*"))
if daysValue then
local hours = daysValue * 24
return string.format("%.2f days (%d hours)", daysValue, hours)
end
return days
end
local function hoursToDays(hours)
local hoursValue = tonumber(hours:match("%d+%.?%d*"))
if hoursValue then
local days = hoursValue / 24
return string.format("%.2f hours (%.2f days)", hoursValue, days)
end
return hours
end
-- Energy conversions
local function joulesToCalories(joules)
local joulesValue = tonumber(joules:match("%d+%.?%d*"))
if joulesValue then
local calories = joulesValue * 0.000239006
return string.format("%.2f joules (%.6f calories)", joulesValue, calories)
end
return joules
end
local function caloriesToJoules(calories)
local caloriesValue = tonumber(calories:match("%d+%.?%d*"))
if caloriesValue then
local joules = caloriesValue / 0.000239006
return string.format("%.2f calories (%.2f joules)", caloriesValue, joules)
end
return calories
end
local function kilowattHoursToJoules(kWh)
local kWhValue = tonumber(kWh:match("%d+%.?%d*"))
if kWhValue then
local joules = kWhValue * 3600000
return string.format("%.2e kWh (%.2e joules)", kWhValue, joules)
end
return kWh
end
local function joulesToKilowattHours(joules)
local joulesValue = tonumber(joules:match("%d+%.?%d*"))
if joulesValue then
local kWh = joulesValue / 3600000
return string.format("%.2e joules (%d kWh)", joulesValue, kWh)
end
return joules
end
-- 🔴Pressure conversions
local function pascalsToPSI(pascals)
local pascalsValue = tonumber(pascals:match("%d+"))
if pascalsValue then
local psi = pascalsValue * 0.000145038
return string.format("%d pascals (%.6f PSI)", pascalsValue, psi)
end
return pascals
end
local function psiToPascals(psi)
local psiValue = tonumber(psi:match("%d+"))
if psiValue then
local pascals = psiValue / 0.000145038
return string.format("%.6f PSI (%d pascals)", psiValue, pascals)
end
return psi
end
local function atmospheresToPascals(atmospheres)
local atmospheresValue = tonumber(atmospheres:match("%d+"))
if atmospheresValue then
local pascals = atmospheresValue * 101325
return string.format("%d atmospheres (%d pascals)", atmospheresValue, pascals)
end
return atmospheres
end
local function pascalsToAtmospheres(pascals)
local pascalsValue = tonumber(pascals:match("%d+"))
if pascalsValue then
local atmospheres = pascalsValue / 101325
return string.format("%d pascals (%.6f atmospheres)", pascalsValue, atmospheres)
end
return pascals
end
-- Frequency conversions
local function hertzToRPM(hertz)
local hertzValue = tonumber(hertz:match("%d+"))
if hertzValue then
local rpm = hertzValue * 60
return string.format("%d Hertz (%d RPM)", hertzValue, rpm)
end
return hertz
end
local function rpmToHertz(rpm)
local rpmValue = tonumber(rpm:match("%d+"))
if rpmValue then
local hertz = rpmValue / 60
return string.format("%d RPM (%.2f Hertz)", rpmValue, hertz)
end
return rpm
end
local function kilohertzToHertz(kHz)
local kHzValue = tonumber(kHz:match("%d+"))
if kHzValue then
local hertz = kHzValue * 1000
return string.format("%d kHz (%d Hertz)", kHzValue, hertz)
end
return kHz
end
local function hertzToKilohertz(hertz)
local hertzValue = tonumber(hertz:match("%d+"))
if hertzValue then
local kHz = hertzValue / 1000
return string.format("%d Hertz (%.2f kHz)", hertzValue, kHz)
end
return hertz
end
-- Power conversions
local function wattsToHorsepower(watts)
local wattsValue = tonumber(watts:match("%d+"))
if wattsValue then
local horsepower = wattsValue * 0.00134102
return string.format("%d watts (%.6f horsepower)", wattsValue, horsepower)
end
return watts
end
local function horsepowerToWatts(horsepower)
local horsepowerValue = tonumber(horsepower:match("%d+"))
if horsepowerValue then
local watts = horsepowerValue / 0.00134102
return string.format("%.6f horsepower (%d watts)", horsepowerValue, watts)
end
return horsepower
end
local function megawattsToHorsepower(megawatts)
local megawattsValue = tonumber(megawatts:match("%d+"))
if megawattsValue then
local horsepower = megawattsValue * 1341.02
return string.format("%d megawatts (%.2f horsepower)", megawattsValue, horsepower)
end
return megawatts
end
local function horsepowerToMegawatts(horsepower)
local horsepowerValue = tonumber(horsepower:match("%d+"))
if horsepowerValue then
local megawatts = horsepowerValue / 1341.02
return string.format("%.2f horsepower (%d megawatts)", horsepowerValue, megawatts)
end
return horsepower
end
-- Add these functions to the p dynamic function to integrate them into the infobox
--❗
local function ftToCm(ft)
local ftValue = tonumber(ft:match("%d+%.?%d*"))
if ftValue then
local cm = ftValue * 30.48
return string.format("%.2f ft (%.2f cm)", ftValue, cm)
end
return ft
end
local function cmToFeetAndInches(cm)
local cmValue = tonumber(cm:match("%d+%.?%d*"))
if cmValue then
local totalInches = cmValue / 2.54
local feet = math.floor(totalInches / 12)
local inches = math.floor(totalInches % 12)
return string.format("%.2f cm (%d feet %d inches)", cmValue, feet, inches)
end
return cm
end
local function mphToKmh(mph)
local mphValue = tonumber(mph:match("%d+%.?%d*"))
if mphValue then
local kmh = mphValue * 1.60934
return string.format("%.2f mph (%.2f km/h)", mphValue, kmh)
end
return mph
end
local function kmhToMph(kmh)
local kmhValue = tonumber(kmh:match("%d+%.?%d*"))
if kmhValue then
local mph = kmhValue / 1.60934
return string.format("%.2f km/h (%.2f mph)", kmhValue, mph)
end
return kmh
end
local function kmToMi(km)
local kmValue = tonumber(km:match("%d+%.?%d*"))
if kmValue then
local miles = kmValue * 0.621371
return string.format("%.2f km (%.2f mi)", kmValue, miles)
end
return km
end
local function miToKm(mi)
local miValue = tonumber(mi:match("%d+%.?%d*"))
if miValue then
local km = miValue / 0.621371
return string.format("%.2f miles (%.2f km)", miValue, km)
end
return mi
end
local function hpToKw(hp)
local hpValue = tonumber(hp:match("%d+%.?%d*"))
if hpValue then
local kw = hpValue * 0.735499
return string.format("%.2f horsepower (%.2f kW)", hpValue, kw)
end
return hp
end
local function kwToHp(kw)
local kwValue = tonumber(kw:match("%d+%.?%d*"))
if kwValue then
local hp = kwValue / 0.735499
return string.format("%.2f Kilowatt(%.2f hp)", kwValue, hp)
end
return kw
end
local function lbToKg(lb)
local lbValue = tonumber(lb:match("%d+%.?%d*"))
if lbValue then
local kg = lbValue * 0.453592
return string.format("%.2f lb (%.2f kg)", lbValue, kg)
end
return lb
end
local function kgToPounds(kg)
--local kgValu = tonumber(kg:match("%d+"))
local kgValue = tonumber(kg:match("%d+%.?%d*"))
if kgValue>1 then
local pounds = kgValue * 2.20462
return string.format("%.2f kgs (%.2f pounds)", kgValue, pounds)
else
local pounds = kgValue * 2.20462
return string.format("%.2f kg (%.2f pounds)", kgValue, pounds)
end
return kg
end
local function mmToInches(mm)
local mmValue = tonumber(mm:match("%d+%.?%d*"))
if mmValue then
local inches = mmValue * 0.0393701
return string.format("%.2f mm (%.2f inches)", mmValue, inches)
end
return mm
end
local function inchesToMm(inches)
local inchesValue = tonumber(inches:match("%d+%.?%d*"))
if inchesValue then
local mm = inchesValue / 0.0393701
return string.format("%.2f inches (%.2f mm)", inchesValue, mm)
end
return inches
end
local function msToFts(ms)
local msValue = tonumber(ms:match("%d+%.?%d*"))
if msValue then
local fts = msValue * 3.28084
return string.format("%.2f m/s(%.2f ft/s)", msValue, fts)
end
return ms
end
local function ftsToMs(fts)
local ftsValue = tonumber(fts:match("%d+%.?%d*"))
if ftsValue then
local ms = ftsValue / 3.28084
return string.format("%.2f ft/s(%.2f m/s)", ftsValue, ms)
end
return fts
end
local function mToFeet(m)
local mValue = tonumber(m:match("%d+%.?%d*"))
if mValue then
local feet = mValue * 3.28084
return string.format("%.2f meter (%.2f ft)", mValue, feet)
end
-- Check for variations of "m", "meter", and "metre"
local mValueAlt = tonumber(m:match("(%d+%.?%d*)%s*[mM]"))
if mValueAlt then
local feetAlt = mValueAlt * 3.28084
return string.format("%.2f m (%.2f ft)", mValueAlt, feetAlt)
end
local mValueAlt2 = tonumber(m:match("(%d+%.?%d*)%s*[mM][eE][tT][eE]?[rR]?"))
if mValueAlt2 then
local feetAlt2 = mValueAlt2 * 3.28084
return string.format("%.2f metre (%.2f ft)", mValueAlt2, feetAlt2)
end
local mValueAlt3 = tonumber(m:match("(%d+%.?%d*)%s*[mM][eE][tT][eE][rR]?"))
if mValueAlt3 then
local feetAlt3 = mValueAlt3 * 3.28084
return string.format("%.2f meter (%.2f ft)", mValueAlt3, feetAlt3)
end
return m
end
--//m///
local function celsiusToFahrenheit(c)
local cValue = tonumber(c:match("%d+"))
if cValue then
local fahrenheit = cValue * 9/5 + 32
return string.format("%.2f°C (%.2f°F)", cValue, fahrenheit)
end
return c
end
local function fahrenheitToCelsius(f)
local fValue = tonumber(f:match("%d+"))
if fValue then
local celsius = (fValue - 32) * 5/9
return string.format("%.2f°F (%.2f°C)", fValue, celsius)
end
return f
end
function capitalizeFirstLetter(str)
return str:gsub("^%l", string.upper)
end
--[[ local conversionPatterns = {
{ pattern = "%s*kilohertz%s*", convertedValue = kilohertzToHertz},
{ pattern = "%s*kg%s*", conversion = kgToPounds },
{ pattern = "%s*mph%s*", conversion = mphToKmh },
-- Add more conversion patterns as needed
} ]]
function p.dynamic(frame)
local args = frame:getParent().args
local output = '<div colspan="2" class="infobox biography vcard" style="max-width: 100vw; width: auto; margin: 0 auto;">\n|-\n'
-- local firstDescriptionFound = false
local cmProcessed = false
local abvParams = {} -- Store abv parameters separately
local abvProcessed = false
local upProcessed = false
local imageProcessed =false
--[[go over arguments to find "up" and "abv" parameters
for key, value in pairs(args) do
if key:sub(1, 2) == 'up' then
if value ~= "" then
output = output .. '<tr><th style='..(args.header or"")..'"background:lightgra;font-size:20px;text-align: center; background-color: ' .. (args.headcolor or "#f2f2f2") .. '; color: ' .. (args.color or "inherit") .. '; font-weight: bold;"> ' .. value .. '\n</th></tr>\n'
upProcessed = true
end
end
end
]]
local values = {}
for key, value in pairs(args) do
if key:sub(1, 2) == 'up' and value ~= "" then
table.insert(values, {key = key, value = value})
end
end
table.sort(values, function(a, b) return a.key < b.key end)
for _, entry in ipairs(values) do
local key = entry.key
local value = entry.value
value = value:gsub("^%l", string.upper)
local first_char = value:match("%a") -- Find the first alphabet character
if first_char then
value = value:gsub("^" .. first_char, string.upper) -- Capitalize the first alphabet character
end
output = output .. '<tr><th style="font-size:20px;text-align:center;background-color:' .. (args.header or "") .. ';color:' .. (args.color or "") .. ';font-weight:bold;" colspan="2">' .. value .. '\n</th></tr>\n'
end
--[[
for key, value in pairs(args) do
if value ~= "" then
if key ~= 'image' and key ~= 'imagecaption' and key ~= 'caption' and key ~= 'headcolor' and key ~= 'color' and key ~= 'abvstyle' and key ~= 'abvheadcolor' and key ~= 'abvcolor'then
if key ~= 'up' and not (key:sub(1, 2) == 'up' and upProcessed) and key ~= 'abv' and not abvProcessed then
-- Your existing conversion logic goes here
end
end
end
end
for key, value in pairs(args) do
if value ~= "" then
if key ~= 'image' and key ~= 'imagecaption' and key ~= 'caption' and key ~= 'headcolor' and key ~= 'color' and key ~= 'abvstyle' and key ~= 'abvheadcolor' and key ~= 'abvcolor'then
if key ~= 'abv' and not (key:sub(1, 3) == 'abv' and abvProcessed) and key ~= 'abv' and not upProcessed then
-- Your existing conversion logic goes here
end
end
end
end
]]
local hasImage = false
for key, _ in pairs(args) do
if key:sub(1, 5) == "image" then
hasImage = true
break
end
end
if not hasImage then
local defaultImage = "[[File:default_image.jpg|thumb|center|Default Image]]\n"
output = output .. defaultImage
end
if args.image then
local processedKeys = {}
local processedSizeCaption = {}
local images = {}
local div = '<div style="display: flex;flex-wrap:wrap;grid-template-columns: repeat(2, 1fr); gap: 2px; text-align: center; margin: 2px;">'
for key, value in pairs(args) do
if key:sub(1, 5) == "image" and value ~= "" and not processedKeys[key] then
processedKeys[key] = true
local captionKey = "caption" .. key:sub(6)
local sizeKey = "size" .. key:sub(6)
if not processedSizeCaption[captionKey] and not processedSizeCaption[sizeKey] then
processedSizeCaption[captionKey] = true
processedSizeCaption[sizeKey] = true
local caption = args[captionKey] or ""
local imagesize = args[sizeKey] or ""
local isFrameless = string.match(value, '|frameless')
local imageExtension = value:match("%.([^.]+)$")
if not imageExtension then
value = value .. ".jpg"
end
local grid =""
local wikiMarkup = ''
if isFrameless then
local remo = value:gsub("(%[%[.-|)File:", "%1")
wikiMarkup = wikiMarkup .. '|' .. '<div style="text-align:center;">' .. remo .. '</div>' .. '<small style="display: block; text-align: center;">' .. caption .. '</small>\n|-\n'
else
local imageName, imageSize = value:match("%[%[File:(.-)|([^|%]]+)]]")
if imageName then
wikiMarkup = wikiMarkup .. "[[File:" .. imageName
if imageSize then
wikiMarkup = wikiMarkup .. "|" .. imageSize
end
wikiMarkup = wikiMarkup .. "]]"
else
local imageSizeMarkup = ""
if imagesize ~= "" then
imageSizeMarkup = "|" .. imagesize
end
wikiMarkup = wikiMarkup .. "[[File:" .. value:gsub("%[%[", ""):gsub("%]%]", "") .. imageSizeMarkup .. "]]"
end
wikiMarkup = '<div style="text-align:center;">' .. wikiMarkup .. '<small style="display: block; text-align: center;">' .. caption .. '</small></div>\n'
end
-- Store the image markup along with its key
table.insert(images, { key = key, markup = wikiMarkup, insertionOrder = #images + 1 }) end
end
end
-- Sort the images based on their keys to maintain the insertion order
--table.sort(images, function(a, b) return a.key < b.key end)
-- Generate the output markup
local columnCount = 0
local gridOpen = false
for _, imageData in ipairs(images) do
local wikiMarkup = imageData.markup
if imageData.key:sub(-1) == "+" then
if not gridOpen then
output = output .. '|<div colspan="2">' .. div.. '</div>\n|-\n' -- Open the grid container if it's not already open
gridOpen = true
end
--output = output ..'|'.. wikiMarkup .. '\n|-\n' -- For keys not ending with '+', display normally
output = output .. '|<div class="grid-item"colspan="2">' .. wikiMarkup .. '</div>\n'
columnCount = (columnCount + 1) % 2
else
if gridOpen then
output = output .. '</div>\n|-\n' -- Close the grid container if it's open
gridOpen = false
end
output = output ..'<tr><th colspan="2">'.. wikiMarkup .. '</th><tr>\n|-\n' -- For keys not ending with '+', display normally
end
end
-- If there are unclosed div tags, close them
if gridOpen then
output = output .. '</div>\n|-\n'
end
end
--[[
if key:sub(6, 6) == "+" then
table.insert(gridImages, {value = value, caption = caption, isFrameless = isFrameless})
else
table.insert(normalImages, {value = value, caption = caption, imagesize = imagesize, isFrameless = isFrameless})
end
end
end
end
-- Begin HTML output for grid layout
local div='<div class="grid-container" style=" display: grid; grid-template-columns: repeat(2, 1fr); gap: 2px; text-align: center; margin-bottom: 5px; ">\n'
-- Output grid images
for _, image in ipairs(gridImages) do
local wikiMarkup = ""
local remo = image.value
wikiMarkup = wikiMarkup .. div.. '<div class="grid-item">' ..'<div style="text-align:center;">'.. remo.. '</div>'..'<small style="display: block; text-align: center;">' .. image.caption .. '</small>\n</div>\n'
output = output .. wikiMarkup
end
if args.image then
local caption = args.caption or ""
local imagesize = args.imagesize or ""
output = output .. '|' ..'<div style="text-align:center;">'.. args.image.. '</div>'..'<small style="display: block; text-align: center;">' .. caption .. '</small>\n|-\n'
end
--///
]]
--[[
]]
--
local values = {}
for key, value in pairs(args) do
if key == key and value ~= "" then
table.insert(values, {key = key, value = value})
end
end
--[[local function generateUUID()
return uuid()
end
]]
local function extractNumber(key)
return tonumber(key:match("^%d+")) or 0
end
--❗ Insertion Sort algorithm
for i = 2, #values do
local current = values[i]
local j = i - 1
while j > 0 and (extractNumber(values[j].key) > extractNumber(current.key) or
(extractNumber(values[j].key) == extractNumber(current.key) and values[j].key > current.key)) do
values[j + 1] = values[j]
j = j - 1
end
values[j + 1] = current
end
--[[
table.sort(values, function(a, b)
local aKey = a.key:match(".*%*$") and 1 or 0
local bKey = b.key:match(".*%*$") and 1 or 0
-- Keys with asterisks should come before keys without asterisks
if aKey ~= bKey then
return aKey < bKey
else
if aKey == 1 and bKey == 1 then
return a.key < b.key
elseif aKey == 0 and bKey == 0 then
local numA = tonumber(a.key)
local numB = tonumber(b.key)
if numA and numB then
return numA < numB
else
return a.key < b.key
end
else
-- If one has asterisk and the other doesn't, prioritize the one with the asterisk
return aKey == 1
end
end
end)
]]
--[[
--Insertion Sort algorithm for modified_key
for i = 2, #values do
local current = values[i]
local j = i - 1
while j > 0 and values[j].key > current.key do
values[j + 1] = values[j]
j = j - 1
end
values[j + 1] = current
end
for i = 2, #values do
local current = values[i]
local j = i - 1
while j > 0 and values[j].key > current.key do
values[j + 1] = values[j]
j = j - 1
end
values[j + 1] = current
end
]]
local matchedKeys = {}
local bgStyles = {} -- Table to store background styles for each matched key
local generatedColors = {}
-- Function to generate contrasting text color for a given background color
local function getContrastingTextColor(bgColor)
-- Convert hex color to RGB
local r = tonumber(bgColor:sub(2, 3), 16)
local g = tonumber(bgColor:sub(4, 5), 16)
local b = tonumber(bgColor:sub(6, 7), 16)
-- Calculate relative luminance
local luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255
-- Choose white or black text color based on luminance
if luminance > 0.5 then
return "#000000" -- Black text for light backgrounds
else
return "#FFFFFF" -- White text for dark backgrounds
end
end
-- Function to generate even lighter colors
function generateEvenLighterColor1()
local r = math.random(0xF0, 0xFF) -- Red component
local g = math.random(0xF0, 0xFF) -- Green component
local b = math.random(0xF0, 0xFF) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
-- Function to generate a very light color
function generateVeryLightColor2()
local r = math.random(0xE0, 0xFF) -- Red component
local g = math.random(0xE0, 0xFF) -- Green component
local b = math.random(0xE0, 0xFF) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
-- Function to generate a random light color
function generateLightColor3()
local r = math.random(0xB0, 0xFF) -- Red component
local g = math.random(0xB0, 0xFF) -- Green component
local b = math.random(0xB0, 0xFF) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
-- Functions to generate mixed light-dark colors
function generateDarkColor4()
local r = math.random(0x60, 0x80) -- Red component
local g = math.random(0x60, 0x80) -- Green component
local b = math.random(0x60, 0x80) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
function generateDarkColor5()
local r = math.random(0x50, 0x70) -- Red component
local g = math.random(0x50, 0x70) -- Green component
local b = math.random(0x50, 0x70) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
function generateDarkColor6()
local r = math.random(0x40, 0x60) -- Red component
local g = math.random(0x40, 0x60) -- Green component
local b = math.random(0x40, 0x60) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
function generateDarkColor7()
local r = math.random(0x20, 0x40) -- Red component
local g = math.random(0x20, 0x40) -- Green component
local b = math.random(0x20, 0x40) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
function generateDarkColor8()
local r = math.random(0x30, 0x70) -- Red component
local g = math.random(0x30, 0x70) -- Green component
local b = math.random(0x30, 0x70) -- Blue component
return string.format("#%02X%02X%02X", r, g, b) -- Format as hexadecimal color
end
function generateDarkColor9()
return string.format("#%02x%02x%02x", math.random(0x30, 0x50), math.random(0x40, 0x70), math.random(0x50, 0x70))
end
function generateDarkColor10()
return string.format("#%06x", math.random(0x30, 0x70))
end
-- Function to generate a random color
local function generateRandomColor()
local r = math.random(0, 255)
local g = math.random(0, 255)
local b = math.random(0, 255)
return string.format("#%02X%02X%02X", r, g, b)
end
for _, entry in ipairs(values) do
local key = entry.key
local value = entry.value
local modified_key = key:gsub("^[%d]*", "")
local found_alpha = false
for i = 1, #modified_key do
if modified_key:sub(i, i):match("%a") then
modified_key = modified_key:sub(1, i - 1) .. modified_key:sub(i, i):upper() .. modified_key:sub(i + 1)
found_alpha = true
break
end
end
if not found_alpha then
modified_key = modified_key:gsub("^.", string.upper, 5)
end
local matched = false
repeat
local bgs = modified_key:match(".*%*$") or ""
if bgs ~= "" and not matchedKeys[modified_key] then
local bgStyle = bgStyles[modified_key]
if not bgStyle then
local manualBgColor = args["bgColor_" .. (modified_key:match(".*%*$"))] or ""
local manualTextColor = args["textColor_" .. (modified_key:match(".*%*$"))] or ""
local bgColor, textColor
if generatedColors[modified_key] then
bgColor, textColor = generatedColors[modified_key].bgColor, generatedColors[modified_key].textColor
else
local randf1=args.rd1 =="yes" or args.Rd1=="yes"
local randf2=args.rd2 =="yes" or args.Rd2=="yes"
local randf3=args.rd3 =="yes" or args.Rd3=="yes"
local randf4=args.rd4 =="yes" or args.Rd4=="yes"
local randf5=args.rd5 =="yes" or args.Rd5=="yes"
local randf6=args.rd6 =="yes" or args.Rd6=="yes"
local randf7=args.rd7 =="yes" or args.Rd7=="yes"
local randf8=args.rd8 =="yes" or args.Rd8=="yes"
local randf9=args.rd9 =="yes" or args.Rd9=="yes"
local randf10=args.rd10 =="yes" or args.Rd10=="yes"
local randf11=args.rd11 =="yes" or args.Rd11=="yes"
local randf12=args.rd12 =="yes" or args.Rd12=="yes"
if manualBgColor ~= "" and manualTextColor ~= "" then
bgColor = manualBgColor
textColor = manualTextColor
elseif randf1 then
bgColor = generateEvenLighterColor1()
textColor = getContrastingTextColor(bgColor)
elseif randf2 then
bgColor = generateVeryLightColor2()
textColor = getContrastingTextColor(bgColor)
elseif randf3 then
bgColor = generateLightColor3()
textColor = getContrastingTextColor(bgColor)
elseif randf4 then
bgColor = generateDarkColor4()
textColor = getContrastingTextColor(bgColor)
elseif randf5 then
bgColor = generateDarkColor5()
textColor = getContrastingTextColor(bgColor)
elseif randf6 then
bgColor = generateDarkColor6()
textColor = getContrastingTextColor(bgColor)
elseif randf7 then
bgColor = generateDarkColor7()
textColor = getContrastingTextColor(bgColor)
elseif randf8 then
bgColor = generateDarkColor8()
textColor = getContrastingTextColor(bgColor)
elseif randf9 then
bgColor = generateDarkColor9()
textColor = getContrastingTextColor(bgColor)
elseif randf10 then
bgColor = generateDarkColor10()
textColor = getContrastingTextColor(bgColor)
elseif randf11 then
bgColor = generateRandomColor()
textColor = getContrastingTextColor(bgColor)
else
bgColor = "#" .. string.format("%06x", math.random(0x000000, 0xFFFFFF))
bgColor = bgColor .. "00" -- append alpha value (00 for fully transparent)
textColor = "#000000"
end
generatedColors[modified_key] = {bgColor = bgColor, textColor = textColor}
end
bgStyle = string.format("background-color: %s; color: %s;", bgColor, textColor)
bgStyles[modified_key] = bgStyle
end
for _, val in pairs(args) do
if val == value and val ~= "" then
local alreadyAdded = string.match(output, val:gsub("^%l", string.upper))
if not alreadyAdded then
output = output .. string.format('<tr><th colspan="2" style="%s; %s; font-size:16px; text-align:center; font-weight:bold;">%s</th>\n</tr>\n', args.style or "", bgStyle, val:gsub("^%l", string.upper))
matchedKeys[modified_key] = true
matched = true
break
end
end
end
end
modified_key = modified_key:gsub("%*+$", "") -- Remove the last asterisks
until not modified_key:match(".*%*+%*$") or matched
--[[ local randFlag = args["*rand"] == "yes" -- Check if *rand=yes flag is present
if randFlag then
bgColor = generateRandomColor() -- Generate a random color
else
-- Handle other cases or default behavior for background color
end
]]
-- Handle infinite occurrences of modified_key:match(".*%*$")
--local modified_key = key:gsub("^%D*(%d+).*", "%1")
--[[
if tonumber(string.sub(key, 1, 1)) ~= nil then
modified_key= string.sub(key, 2) -- Exclude the first character if it's a number
end
]]
if key ~= 'image'and not key:match("^image[%a%d]+$") --[[and not (key:sub(1, 5)=="image")]]
and key ~= 'caption' and not key:match(".*%*$")
and key ~= 'headcolor' and key ~= 'color' and key~='header'
and not key:match("^abv%d+$")and not key:match("^up[%a%d]+$") then
if key ~= 'up' and not (key:sub(1, 2) == 'up'=="image"and upProcessed) and key ~= 'abv'and key~="imagesize" and key~="rd" and not abvProcessed and not key:match("^Rd%d+$")then
--if key ~= 'up' and not (key:sub(1, 2) == 'up' and upProcessed) then
if key ~= 'abv' and not (key:sub(1, 3) == 'abv' and abvProcessed) and not key:match("^rd%d+$") then
if key~="size" and not key:match("^size[%a%d]+$")and not(key:sub(-1)=="+") and not key:match("^caption[%a%d]+$") and key~="rd" then
--//m
local convertedValue = value
local originalValue = value
if not cmProcessed and (value:match("%s*cm#%s*")or value:match("%s*centimeters#%s*")or value:match("%s*centimetres#%s*") or value:match("%s*centimeter#%s*") or value:match("%s*centimetre#%s*")) then
-- If centimeters conversion not done yet, do it here
--cmProcessed = true
convertedValue = cmToFeetAndInches(value)
end
--/////❗
if type(value) == "string" then
local age=dateCalculation(value)
--[[]]
--local ag = calculateAg(value )
--if value:match("%d%d%d%d[/.-]%d%d[/.-]%d%d[./-]") then
if value:match("%d+%d+%d+[./-]") then
--value =value:gsub("(%d%d%d%d)[/.-](%d%d)[/.-](%d%d)[./-]", "%1".. age )--:gsub("(%d%d%d%d)", "")
value =value:gsub("(%d+%d+%d+)[/.-]", "".. age ):gsub("%d+[./-]", "")--:gsub("(%d%d%d%d)[/.-](%d%d)[/.-](%d%d)[./-]", "".. age )
--else
--value="Invalid date format"
end
--end
value = value:gsub("(%d+[/.%-]+%d+[/.%-]+%d+[%d/.%-]*)", ""):gsub("(%d+[/.%-]+%d+[/.%-]+%d+[%d/.%-]*)", ""):gsub("<i></i>", "")
value = value:gsub("(%d+[/.,-]%d+[/.,-]%d+)", "")
--[[
if value:match("%d+%d+%d+[/.,~]") then
value = value:gsub("(%d+%d+%d+)[/.,~]", "%1<i></i>"..age)
end
value = value:gsub("(%d%d%d%d)[. /-] (%d%d)[/-.] (%d%d)", ""):gsub("(%d%d)[. - /] (%d%d)", ""):gsub("<i></i>", "")
--value = value:gsub("(%d%d%d%d)%p(%d%d)%p(%d%d)", ""):gsub("<i></i>", "")
]]
if value:match("%s*cm%W%s*")or value:match("%s*centimeters#%s*")or value:match("%s*centimetres#%s*") or value:match("%s*centimeter#%s*") or value:match("%s*centimetre#%s*") then
convertedValue = cmToFeetAndInches(value)..""
elseif value:match("%s*kg%W%s*") or value:match("%s*kgs#%s*")or value:match("%s*kilograms#%s*") or value:match("%s*kilogram#%s*") then
convertedValue = kgToPounds(value)
elseif value:match("%s*mph#%s*")or value:match("%s*mp/h#%s*")or value:match("%s*miles per hour#%s*")or value:match("%s*mile per hour#%s*") then
convertedValue = mphToKmh(value)
elseif value:match("%s*kmh#%s*")or value:match("%s*km/h#%s*")or value:match("%s*kilometers per hour#%s*")or value:match("%s*kilometer per hour#%s*")or value:match("%s*kilometres per hour#%s*")or value:match("%s*kilometre per hour#%s*") then
convertedValue = kmhToMph(value)
elseif value:match("%s*kms#%s*")or value:match("%s*km#%s*")or value:match("%s*kilometer#%s*")or value:match("%s*kilometers#%s*")or value:match("%s*kilometre#%s*")or value:match("%s*kilometres#%s*") then
convertedValue = kmToMi(value)
elseif value:match("%s*mi#%s*")or value:match("%s*mile#%s*")or value:match("%s*miles#%s*") then
convertedValue = miToKm(value)
elseif value:match("%s*hp#%s*")or value:match("%s*hps#%s*")or value:match("%s*horsepower#%s*")or value:match("%s*horsepowers#%s*") then
convertedValue = hpToKw(value)
elseif value:match("%s*kw#%s*")or value:match("%s*kws#%s*")or value:match("%s*kilowatt#%s*")or value:match("%s*kilowatts#%s*") then
convertedValue = kwToHp(value) elseif value:match("%s*ft#%s*") then elseif value:match("%s*lb#%s*")or value:match("%s*pound#%s*")or value:match("%s*pounds#%s*") then
convertedValue = lbToKg(value)
elseif value:match("%s*mmms#%s*")or value:match("%s*mm#%s*")or value:match("%s*millimeter#%s*")or value:match("%s*millimetre#%s*")or value:match("%s*millimeters#%s*")or value:match("%s*millimetres#%s*") then
convertedValue = mmToInches(value)
elseif value:match("%s*in#%s*")or value:match("%s*ins#%s*")or value:match("%s*inch#%s*")or value:match("%s*inche#%s*")or value:match("%s*inches#%s*") then
convertedValue = inchesToMm(value)
elseif value:match("%s*ms#%s*")or value:match("%s*millisecond#%s*")or value:match("%s*milliseconds#%s*") then
convertedValue = msToFts(value)
elseif value:match("%s*fts#%s*")or value:match("%s*ft/s#%s*")or value:match("%s*fps#%s*")or value:match("%s*footperseconds#%s*") then
convertedValue = ftsToMs(value)
elseif value:match("%s*°c#%s*") or value:match("%s*celsius#%s*") or value:match("%s*Celsius#%s*") then
convertedValue = celsiusToFahrenheit(value)
elseif value:match("%s*°f#%s*") or value:match("%s*fahrenheit#%s*") then
convertedValue = fahrenheitToCelsius(value)
--❗
elseif value:match("%s*liters#%s*")or value:match("%s*litres#%s*")or value:match("%s*litre#%s*")or value:match("%s*liter#%s*") then
convertedValue = litersToGallons(value)
elseif value:match("%s*gallons#%s*")or value:match("%s*gallon#%s*") then
convertedValue = gallonsToLiters(value)
elseif value:match("%s*m³#%s*")or value:match("%s*m3#%s*")or value:match("%s*cubicmeters#%s*")or value:match("%s*cubicmetres#%s*")or value:match("%s*cubicmetre#%s*")or value:match("%s*cubicmeter#%s*") then
convertedValue = cubicMetersToCubicFeet(value)
elseif value:match("%s*ft³#%s*")or value:match("%s*ft3#%s*")or value:match("%s*cubicfeet#%s*")or value:match("%s*cubicfoot#%s*")or value:match("%s*cubicfeets#%s*")or value:match("%s*cubicfoots#%s*") then
convertedValue = cubicFeetToCubicMeters(value) elseif value:match("%s*sqm#%s*")or value:match("%s*sqms#%s*")or value:match("%s*sqmetre#%s*")or value:match("%s*sqmetres#%s*")or value:match("%s*squaremeter#%s*")or value:match("%s*squaremeters#%s*")or value:match("%s*sqmeter#%s*")or value:match("%s*sqmeters#%s*") then
convertedValue = squareMetersToSquareFeet(value)
elseif value:match("%s*sqft#%s*")or value:match("%s*sqfoot#%s*")or value:match("%s*sqfeet#%s*")or value:match("%s*squarefoots#%s*")or value:match("%s*squarefeets#%s*")or value:match("%s*squarefeet#%s*") then
convertedValue = squareFeetToSquareMeters(value)
elseif value:match("%s*hectares#%s*")or value:match("%s*hectare#%s*") then
convertedValue = hectaresToAcres(value)
elseif value:match("%s*acres#%s*")or value:match("%s*acre#%s*") then
convertedValue = acresToHectares(value)
elseif value:match("%s*hours#%s*")or value:match("%s*hour#%s*") then
convertedValue = hoursToMinutes(value)
elseif value:match("%s*minutes#%s*")or value:match("%s*minute#%s*") then
convertedValue = minutesToHours(value)
elseif value:match("%s*days#%s*")or value:match("%s*day#%s*") then
convertedValue = daysToHours(value)
elseif value:match("%s*joules#%s*")or value:match("%s*joule#%s*") then
convertedValue = joulesToCalories(value)
elseif value:match("%s*calories#%s*")or value:match("%s*calorie#%s*") then
convertedValue = caloriesToJoules(value)
elseif value:match("%s*kwh#%s*")or value:match("%s*kilowatthours#%s*")or value:match("%s*kilowatthour#%s*") then
convertedValue = kilowattHoursToJoules(value)
elseif value:match("%s*psi#%s*")or value:match("%s*pounds per square inch#%s*")or value:match("%s*pound per square inches#%s*") then
convertedValue = psiToPascals(value)
elseif value:match("%s*pascals#%s*")or value:match("%s*pascal#%s*") then
convertedValue = pascalsToPsi(value)
elseif value:match("%s*atm#%s*")or value:match("%s*atmospheres#%s*")or value:match("%s*atmosphere#%s*") then
convertedValue = atmospheresToPascals(value)
elseif value:match("%s*rpm#%s*") then
convertedValue = rpmToHertz(value)
elseif value:match("%s*kilohertz#%s*")or value:match("%s*khz#%s*") then
convertedValue = kilohertzToHertz(value)
elseif value:match("%s*hertz#%s*") then
convertedValue = hertzToRPM(value)
elseif value:match("%s*horsepower#%s*") then
convertedValue = horsepowerToWatts(value)
elseif value:match("%s*megawatts#%s*") or value:match("%s*megawatt#%s*")then
convertedValue = megawattsToHorsepower(value)
elseif value:match("%s*watts#%s*") or value:match("%s*watt#%s*")then
convertedValue = wattsToHorsepower(value)
elseif value:match("%s*hp#%s*") then
convertedValue = horsepowerToMegawatts(value)
elseif value:match("%s*m#%s*")or value:match("%s*meters#%s*")or value:match("%s*metres#%s*")or value:match("%s*meter#%s*")or value:match("%s*metre#%s*") then
convertedValue = mToFeet(value)
elseif value:match("%s*ft%W%s*") or value:match("%s*feet%P%s*")or value:match("%s*feets%P%s*")or value:match("%s*foot%P%s*")or value:match("%s*foots%P%s*") then
local ft=convertedValue
convertedValue =convertValue:gsub("^ft[%a%d]+$", "" .. ft) --ftToCm(value)
elseif value:match("%d%d[/.-]%d%d[/.-]%d%d%d%d[./-]") then
value="Invalid date format"
--value =value:gsub("(%d%d)[/.-](%d%d)[/.-](%d%d%d%d)[./-]", "%1".. age ):gsub("(%d+%d+%d+)", "")
end
--local age=calculateAge(value)
--value = value:gsub("(%d+[/.,-]%d+[/.,-]%d+)", "")
--❗ modified_key = key:gsub("^[_%d]*", "")
value = value:gsub("^%l", string.upper)
local first_char = value:match("%a") -- Find the first alphabet character
if first_char then
value = value:gsub("^" .. first_char, string.upper) -- Capitalize the first alphabet character
end
output = output .. '| style="font-size:15px; font-weight:bolder;padding-right:1em;" | ' ..modified_key:gsub("^[_()%-%d]*", "") .. "\n"
if originalValue ~= convertedValue then
output = output .. '| '..convertedValue.. '\n|-\n'
else
output = output .. '| ' .. value .. '\n|-\n'
end
--[[
if value:match("%d+%d+%d+[/.,~-]") then
local age = calculateAg(value)
if age ~= "Invalid date format" then
value = value:gsub("(%d+%d+%d+)[/.,~]", "%1<i></i>" .. age)
end
end
value = value:gsub("(%d+[/.,-]%d+[/.,-]%d+)", "")
V]]
--[[]]
--local matchedKeys = {}
--[[
local processedValues = {} -- Set to store processed values
for key, value in pairs(args) do
if key:match(".*%*$") and value ~= "" and not processedValues[value] then
output = output .. '<tr><th style="' .. (args.header or "") .. '; background:lightgray; font-size:20px; text-align:center; background-color:' .. (args.headcolor or "#f2f2f2") .. '; color:' .. (args.color or "inherit") .. '; font-weight:bold;">' .. value .. '</th></tr>\n'
processedValues[value] = true
end
end
]]
-- print(modified_key, value) -- You can modify this to suit your needs
--[[
if value:match("%d+/%d+/%d+")then
age=calculateAge(value)
if age then
value =value..' (' .. age .. ')'
output = output .. '| style="font-weight:bolder;padding-right:1em;" | ' .. capitalizeFirstLetter(key) .. "'''<br />\n"
if originalValue ~= value then
output = output .. '| '..value .. '\n|-\n'
else
output = output .. '| ' .. value .. '\n|-\n'
end
end
end
]]
end
end
end
end
end
end
--[[
local values = {}
for key, value in pairs(args) do
if key:sub(1, 3) == 'abv' and value ~= "" then
table.insert(values, {key = key, value = value})
end
end
table.sort(values, function(a, b) return a.key < b.key end)
for _, entry in ipairs(values) do
local key = entry.key
local value = entry.value
output = output .. '| style="background:lightgray;font-size:20px;text-align:center;background-color:' .. (args.abvheadcolor or "#f2f2f2") .. ';color:' .. (args.abvcolor or "inherit") .. ';font-weight:bold;" | ' .. value .. '\n|-\n'
end
]]
local values = {}
for key, value in pairs(args) do
if key:sub(1, 3) == "abv" and value ~= "" then
table.insert(values, {key = key, value = value, position = mw.ustring.match(key, "%d+")})
end
end
table.sort(values, function(a, b) return tonumber(a.position) < tonumber(b.position) end)
for _, entry in ipairs(values) do
local key = entry.key
local value = entry.value
value = value:gsub("^%l", string.upper)
local first_char = value:match("%a") -- Find the first alphabet character
if first_char then
value = value:gsub("^" .. first_char, string.upper) -- Capitalize the first alphabet character
end
output = output .. '<tr><th colspan="2" style="font-size:20px;text-align:center;background-color:' .. (args.downheader or "rgba(0,0,0,0.020)") .. ';color:' .. (args.downcolor or "") .. ';font-weight:bold;"> ' .. value .. '</th></tr>\n|-\n'
end
output = output .. '</div>\n'
return output
end
return p