Module:Sandbox/Thisasia
Appearance
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 '
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
--[[
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
]]
--❗
--[[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
-- 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
--[[ 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:grid;grid-template-columns: repeat(2, auto); 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:gsub("|", "".. ".jpg|").. ".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
local values = {}
for key, value in pairs(args) do
if key:sub(1, 3) == "mdl"or key:match("^(%d+)mdl") 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
-- local transcludedContent = transcludeTemplate("User:Thisasia/sandbox3", { value = "" })
--output = output .. '<tr><th colspan="2" style="font-size:20px;text-align:center;background-color:' .. (args.downheade or "rgba(0,0,0,0.020)") .. ';color:' .. (args.downcolo or "") .. ';font-weight:bold;"> {{User:Thisasia/Signature|'.. frame:preprocess('{{User:Thisasia/Signature|'.. value.. '}}').. value .. '}}</th></tr>\n|-\n'
output = output .. '<tr><th colspan="2" style="font-size:20px;text-align:center;background-color:' .. (args.downheade or "rgba(0,0,0,0.020)") .. ';color:' .. (args.downcolo or "") .. ';font-weight:bold;">'.. value .. '</th></tr>\n|-\n'
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 = 1, #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 = {}
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]+$") and not key:match("^%d+mdl[%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+$") and not key:match("^mdl[%a%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"and not(key:sub(1, 3)=="mdl") and not key:match("^(%d+)mdl") 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
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
mw.text.unstrip
local frame = mw.getCurrentFrame()
--local infoboxContent = frame:preprocess('{{User:Thisasia/Signature|' ..value..'}}')
local function transcludeTemplate(templateName, args)
local frame = mw.getCurrentFrame()
local templateContent = frame:expandTemplate { title = templateName, args = args }
return templateContent
end
]]
--local frame = mw.getCurrentFrame()
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
-- local transcludedContent = transcludeTemplate("User:Thisasia/sandbox3", { value = "" })
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;"> '.. frame:preprocess('{{User:Thisasia/sandbox3|'..value) .. '</th></tr>\n|-\n'
end
output = output .. '</div>\n'
return output
end
return p