Jump to content

Module:Sandbox/S.A. Julio

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by S.A. Julio (talk | contribs) at 19:18, 4 December 2024 (.). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.
local p = {}

local function cleanFractions(text)
    -- Remove span tags with specific classes while preserving content
    text = text:gsub('<span class="frac">([^<]*)<span class="sr%-only">[^<]*</span><span class="num">([^<]*)</span>%&frasl;<span class="den">([^<]*)</span></span>', '%1+%2/%3')
    return text
end

local function removeReferences(text)
    return text:gsub('\127[^\127]*UNIQ%-%-[^\127]*%%-%x+%-QINU[^\127]*\127', '')
end

local function splitHeights(text)
    -- Find the position of the opening parenthesis
    local parenStart = text:find('%s*%(')
    if not parenStart then 
        mw.log('Split heights failed: No opening parenthesis found')
        return nil, nil 
    end
    
    -- Split into regular and converted heights
    local regularHeight = text:sub(1, parenStart-1)
    local fullConvertedHeight = text:match('%(([^)]+)%)')
    if not fullConvertedHeight then 
        mw.log('Split heights failed: No closing parenthesis found')
        return nil, nil 
    end

    -- Check if remaining text is exactly ' ()'
    local remaining = text:gsub(regularHeight:gsub("[%+%-%.]", "%%%1"), '', 1):gsub('%(' .. fullConvertedHeight:gsub("[%+%-%.]", "%%%1") .. '%)', '%(%)') -- Escape special characters
    mw.log('Split heights debug - original text: "' .. text .. '"')
    mw.log('Split heights debug - regularHeight: "' .. regularHeight .. '"')
    mw.log('Split heights debug - fullConvertedHeight: "' .. fullConvertedHeight .. '"')
    mw.log('Split heights debug - remaining: "' .. remaining .. '"')
    if remaining ~= ' ()' then 
        mw.log('Split heights failed: Unexpected text found: "' .. remaining .. '"')
        return nil, nil 
    end
    
    return regularHeight, fullConvertedHeight
end

local function checkImperialFormat(height)
    -- Check for standard format: X ft Y in or X ft Y+N/D in
    -- Changed pattern to use simple Lua pattern matching
    local feet, inches, rest = height:match('^(%d+)&nbsp;ft%s+(%d+)(&nbsp;in)$')
    if not feet then
        -- Try matching fraction pattern separately
        feet, inches, numerator, denominator = height:match('^(%d+)&nbsp;ft%s+(%d+)%+(%d+)%/(%d+)&nbsp;in$')
    end
    
    if not feet then 
        mw.log('Imperial format check failed: Format does not match expected pattern. Height: "' .. height .. '"')
        return false 
    end

    feet = tonumber(feet)
    inches = tonumber(inches)
    
    -- Check feet and inches ranges
    if feet < 5 or feet > 6 then
        mw.log('Imperial format check failed: Feet value ' .. feet .. ' is outside allowed range (5-6)')
        return false
    end
    if inches < 0 or inches > 11 then
        mw.log('Imperial format check failed: Inches value ' .. inches .. ' is outside allowed range (0-11)')
        return false
    end
    
    -- If fraction present, check N/D
    if numerator and denominator then
        numerator = tonumber(numerator)
        denominator = tonumber(denominator)
        if not (denominator > 1 and numerator < denominator) then
            mw.log('Imperial format check failed: Invalid fraction ' .. numerator .. '/' .. denominator .. ' (denominator must be > 1 and numerator must be > denominator)')
            return false
        end
    end
    
    return true
end

local function checkMetricFormat(height, metricType)
    -- Check for meters format: X.XX m
    if metricType == 'm' or metricType == 'both' then
        local meters = height:match('^(%d+%.%d%d)&nbsp;m$')
        if meters then
            local value = tonumber(meters) * 100
            if value >= 150 and value <= 213 then
                return true
            else
                mw.log('Metric format check failed: Value ' .. value .. ' cm is outside allowed range (150-213)')
            end
        elseif metricType == 'm' then
            mw.log('Metric format check failed: Format does not match meters pattern. Height: "' .. height .. '"')
        end
    end
    
    -- Check for centimeters format: XXX cm
    if metricType == 'cm' or metricType == 'both' then
        local cm = height:match('^(%d+)&nbsp;cm$')
        if cm then
            local value = tonumber(cm)
            if value >= 150 and value <= 213 then
                return true
            else
                mw.log('Metric format check failed: Value ' .. value .. ' cm is outside allowed range (150-213)')
            end
        elseif metricType == 'cm' then
            mw.log('Metric format check failed: Format does not match centimeters pattern. Height: "' .. height .. '"')
        end
    end
    
    return false
end

function p.main(frame)
    -- Load necessary modules
    local personHeight = require('Module:Person height')
    local arguments = require('Module:Arguments')

    -- Get arguments
    local args = arguments.getArgs(frame, {trim = true})
    local height = args[1]
    local metricType = args.metric or 'both'
    local category = args.cat

    mw.log('Processing height: "' .. height .. '" with metric type: ' .. metricType)
    
    -- Process height
    height = personHeight.main({height, enforce='m', ri='cmin'})
    mw.log('Height after person height module: "' .. height .. '"')
    
    -- Clean fractions and references
    height = cleanFractions(height)
    mw.log('Height after cleaning fractions: "' .. height .. '"')
    height = removeReferences(height)
    mw.log('Height after removing references: "' .. height .. '"')
    
    -- Split into regular and converted heights
    local regularHeight, convertedHeight = splitHeights(height)
    if not regularHeight or not convertedHeight then
        -- Add error category if split failed
        if category then
            mw.log('Adding to category due to height split failure')
            return mw.getCurrentFrame():expandTemplate{
                title = 'main other',
                args = {'[[Category:' .. category .. ']]'}
            }
        end
        return ''
    end
    
    mw.log('Regular height: "' .. regularHeight .. '"')
    mw.log('Converted height: "' .. convertedHeight .. '"')
    
    -- Check formatting based on which appears first
    local isImperialFirst = regularHeight:match('ft')
    local regularValid, convertedValid
    
    if isImperialFirst then
        mw.log('Checking imperial format first')
        regularValid = checkImperialFormat(regularHeight)
        convertedValid = checkMetricFormat(convertedHeight, metricType)
    else
        mw.log('Checking metric format first')
        regularValid = checkMetricFormat(regularHeight, metricType)
        convertedValid = checkImperialFormat(convertedHeight)
    end
    
    -- Add category if any check failed
    if not (regularValid and convertedValid) and category then
        mw.log('Adding to category due to format check failure')
        return mw.getCurrentFrame():expandTemplate{
            title = 'main other',
            args = {'[[Category:' .. category .. ']]'}
        }
    end
    
    return ''
end

return p